From 2059e7ae18fd7e4fc1419434df55cafc0106ed44 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Tue, 13 Dec 2022 17:41:39 +0200 Subject: [PATCH 001/207] UI: Add setting enable selection for flot widget --- .../home/components/widget/lib/flot-widget.models.ts | 1 + .../modules/home/components/widget/lib/flot-widget.ts | 7 +++++-- .../chart/flot-widget-settings.component.html | 11 ++++++++--- .../settings/chart/flot-widget-settings.component.ts | 2 ++ ui-ngx/src/assets/locale/locale.constant-en_US.json | 1 + 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts index 78c9245614..0e6b5bb316 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts @@ -128,6 +128,7 @@ export interface TbFlotYAxisSettings { export interface TbFlotBaseSettings { stack: boolean; + enableSelection: boolean; shadowSize: number; fontColor: string; fontSize: number; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts index d71d9e84f2..89d6ddfaf3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts @@ -118,6 +118,8 @@ export class TbFlot { private mouseleaveHandler = this.onFlotMouseLeave.bind(this); private flotClickHandler = this.onFlotClick.bind(this); + private enableSelection: boolean; + private readonly showTooltip: boolean; private readonly animatedPie: boolean; private pieDataAnimationDuration: number; @@ -132,6 +134,7 @@ export class TbFlot { this.chartType = this.chartType || 'line'; this.settings = ctx.settings as TbFlotSettings; this.utils = this.ctx.$injector.get(UtilsService); + this.enableSelection = isDefined(this.settings.enableSelection) ? this.settings.enableSelection : true; this.showTooltip = isDefined(this.settings.showTooltip) ? this.settings.showTooltip : true; this.tooltip = this.showTooltip ? $('#flot-series-tooltip') : null; if (this.tooltip?.length === 0) { @@ -168,7 +171,7 @@ export class TbFlot { }; if (this.chartType === 'line' || this.chartType === 'bar' || this.chartType === 'state') { - this.options.selection = { mode : 'x' }; + this.options.selection = { mode: this.enableSelection ? 'x' : null }; this.options.xaxes = []; this.xaxis = { mode: 'time', @@ -1251,7 +1254,7 @@ export class TbFlot { this.$element.css('pointer-events', ''); this.$element.addClass('mouse-events'); if (this.chartType !== 'pie') { - this.options.selection = {mode: 'x'}; + this.options.selection = {mode: this.enableSelection ? 'x' : null}; this.$element.bind('plotselected', this.flotSelectHandler); this.$element.bind('dblclick', this.dblclickHandler); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html index 06b9bc5f86..a3758665f0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html @@ -18,9 +18,14 @@
widgets.chart.common-settings - - {{ 'widgets.chart.enable-stacking-mode' | translate }} - +
+ + {{ 'widgets.chart.enable-stacking-mode' | translate }} + + + {{ 'widgets.chart.enable-selection' | translate }} + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts index 8d00d55b63..a9b2812d5d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts @@ -44,6 +44,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; export function flotDefaultSettings(chartType: ChartType): Partial { const settings: Partial = { stack: false, + enableSelection: true, fontColor: '#545454', fontSize: 10, showTooltip: true, @@ -145,6 +146,7 @@ export class FlotWidgetSettingsComponent extends PageComponent implements OnInit // Common settings stack: [false, []], + enableSelection: [true, []], fontSize: [10, [Validators.min(0)]], fontColor: ['#545454', []], 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 3df8a15e52..358cff401d 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3764,6 +3764,7 @@ "chart": { "common-settings": "Common settings", "enable-stacking-mode": "Enable stacking mode", + "enable-selection": "Enable selection", "line-shadow-size": "Line shadow size", "display-smooth-lines": "Display smooth (curved) lines", "default-bar-width": "Default bar width for non-aggregated data (milliseconds)", From d5e6b8e7efca18b41f5263e363c8bcb19bf0ae43 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Mon, 19 Dec 2022 17:12:11 +0200 Subject: [PATCH 002/207] UI: Refactoring checkbox to select --- .../widget/lib/flot-widget.models.ts | 4 ++- .../home/components/widget/lib/flot-widget.ts | 30 +++++++++++++++---- .../chart/flot-widget-settings.component.html | 20 +++++++++++-- .../chart/flot-widget-settings.component.ts | 4 +-- .../assets/locale/locale.constant-en_US.json | 6 +++- 5 files changed, 52 insertions(+), 12 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts index 0e6b5bb316..1ec9e7b994 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts @@ -128,7 +128,7 @@ export interface TbFlotYAxisSettings { export interface TbFlotBaseSettings { stack: boolean; - enableSelection: boolean; + enableSelection: FlotSelection; shadowSize: number; fontColor: string; fontSize: number; @@ -170,6 +170,8 @@ export interface TbFlotGraphSettings extends TbFlotBaseSettings, export declare type BarAlignment = 'left' | 'right' | 'center'; +export declare type FlotSelection = 'enable' | 'disable' | 'mobile' | 'desktop'; + export interface TbFlotBarSettings extends TbFlotBaseSettings, TbFlotThresholdsSettings, TbFlotComparisonSettings, TbFlotCustomLegendSettings { defaultBarWidth: number; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts index 89d6ddfaf3..19f667310b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts @@ -37,7 +37,7 @@ import { widgetType } from '@app/shared/models/widget.models'; import { - ChartType, + ChartType, FlotSelection, TbFlotAxisOptions, TbFlotHoverInfo, TbFlotKeySettings, @@ -118,7 +118,8 @@ export class TbFlot { private mouseleaveHandler = this.onFlotMouseLeave.bind(this); private flotClickHandler = this.onFlotClick.bind(this); - private enableSelection: boolean; + private enableSelection: FlotSelection; + private selectionMode: 'x' | null; private readonly showTooltip: boolean; private readonly animatedPie: boolean; @@ -134,7 +135,8 @@ export class TbFlot { this.chartType = this.chartType || 'line'; this.settings = ctx.settings as TbFlotSettings; this.utils = this.ctx.$injector.get(UtilsService); - this.enableSelection = isDefined(this.settings.enableSelection) ? this.settings.enableSelection : true; + this.enableSelection = isDefined(this.settings.enableSelection) ? this.settings.enableSelection : 'enable'; + this.checkSelectionMode(); this.showTooltip = isDefined(this.settings.showTooltip) ? this.settings.showTooltip : true; this.tooltip = this.showTooltip ? $('#flot-series-tooltip') : null; if (this.tooltip?.length === 0) { @@ -171,7 +173,7 @@ export class TbFlot { }; if (this.chartType === 'line' || this.chartType === 'bar' || this.chartType === 'state') { - this.options.selection = { mode: this.enableSelection ? 'x' : null }; + this.options.selection = { mode: this.selectionMode }; this.options.xaxes = []; this.xaxis = { mode: 'time', @@ -587,6 +589,24 @@ export class TbFlot { this.createPlot(); } + mobileModeChanged() { + this.checkSelectionMode(); + this.options.selection = { mode: this.selectionMode }; + this.redrawPlot(); + } + + private checkSelectionMode() { + if (this.enableSelection === 'enable') { + this.selectionMode = 'x'; + } else if (this.enableSelection === 'mobile' && this.ctx.isMobile) { + this.selectionMode = 'x'; + } else if (this.enableSelection === 'desktop' && !this.ctx.isMobile) { + this.selectionMode = 'x'; + } else { + this.selectionMode = null; + } + } + public update() { if (this.updateTimeoutHandle) { clearTimeout(this.updateTimeoutHandle); @@ -1254,7 +1274,7 @@ export class TbFlot { this.$element.css('pointer-events', ''); this.$element.addClass('mouse-events'); if (this.chartType !== 'pie') { - this.options.selection = {mode: this.enableSelection ? 'x' : null}; + this.options.selection = {mode: this.selectionMode}; this.$element.bind('plotselected', this.flotSelectHandler); this.$element.bind('dblclick', this.dblclickHandler); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html index a3758665f0..19280f8d45 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html @@ -22,9 +22,23 @@ {{ 'widgets.chart.enable-stacking-mode' | translate }} - - {{ 'widgets.chart.enable-selection' | translate }} - + + widgets.chart.selection + + + {{ 'widgets.chart.selection-enable' | translate }} + + + {{ 'widgets.chart.selection-disable' | translate }} + + + {{ 'widgets.chart.selection-mobile' | translate }} + + + {{ 'widgets.chart.selection-desktop' | translate }} + + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts index a9b2812d5d..ac137dc388 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts @@ -44,7 +44,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; export function flotDefaultSettings(chartType: ChartType): Partial { const settings: Partial = { stack: false, - enableSelection: true, + enableSelection: 'enable', fontColor: '#545454', fontSize: 10, showTooltip: true, @@ -146,7 +146,7 @@ export class FlotWidgetSettingsComponent extends PageComponent implements OnInit // Common settings stack: [false, []], - enableSelection: [true, []], + enableSelection: ['enable', []], fontSize: [10, [Validators.min(0)]], fontColor: ['#545454', []], 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 358cff401d..d8808cf5e9 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3764,7 +3764,11 @@ "chart": { "common-settings": "Common settings", "enable-stacking-mode": "Enable stacking mode", - "enable-selection": "Enable selection", + "selection": "Time range selection", + "selection-enable": "Enable", + "selection-disable": "Disable", + "selection-mobile": "Only mobile", + "selection-desktop": "Only desktop", "line-shadow-size": "Line shadow size", "display-smooth-lines": "Display smooth (curved) lines", "default-bar-width": "Default bar width for non-aggregated data (milliseconds)", From 9a1546f2b95a68f8b5c132e2df7662926c9833b1 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Tue, 20 Dec 2022 12:50:53 +0200 Subject: [PATCH 003/207] UI: Upgrade widget bundles --- .../src/main/data/json/system/widget_bundles/charts.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/src/main/data/json/system/widget_bundles/charts.json b/application/src/main/data/json/system/widget_bundles/charts.json index de32604dbb..452755f083 100644 --- a/application/src/main/data/json/system/widget_bundles/charts.json +++ b/application/src/main/data/json/system/widget_bundles/charts.json @@ -153,7 +153,7 @@ "resources": [], "templateHtml": "", "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", - "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'state'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onLatestDataUpdated = function() {\n self.ctx.flot.latestDataUpdate();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.typeParameters = function() {\n return {\n stateData: true,\n hasAdditionalLatestDataKeys: true\n };\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n", + "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'state'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.mobileModeChanged();\n}\n\nself.onLatestDataUpdated = function() {\n self.ctx.flot.latestDataUpdate();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.typeParameters = function() {\n return {\n stateData: true,\n hasAdditionalLatestDataKeys: true\n };\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n", "settingsSchema": "{}", "dataKeySettingsSchema": "{}", "settingsDirective": "tb-flot-line-widget-settings", @@ -174,7 +174,7 @@ "resources": [], "templateHtml": "", "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", - "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onLatestDataUpdated = function() {\n self.ctx.flot.latestDataUpdate();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasAdditionalLatestDataKeys: true\n };\n}\n", + "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx);\n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.mobileModeChanged();\n}\n\nself.onLatestDataUpdated = function() {\n self.ctx.flot.latestDataUpdate();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasAdditionalLatestDataKeys: true\n };\n}\n", "settingsSchema": "{}", "dataKeySettingsSchema": "{}", "latestDataKeySettingsSchema": "{}", @@ -196,7 +196,7 @@ "resources": [], "templateHtml": "", "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", - "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'bar'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onLatestDataUpdated = function() {\n self.ctx.flot.latestDataUpdate();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasAdditionalLatestDataKeys: true\n };\n}\n", + "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'bar');\n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.mobileModeChanged();\n}\n\nself.onLatestDataUpdated = function() {\n self.ctx.flot.latestDataUpdate();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasAdditionalLatestDataKeys: true\n };\n}\n", "settingsSchema": "{}", "dataKeySettingsSchema": "{}", "settingsDirective": "tb-flot-bar-widget-settings", From 245143a988d79fc52105fe5a7376ae4b1cb44d37 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Tue, 20 Dec 2022 16:23:21 +0200 Subject: [PATCH 004/207] UI: Refactoring --- .../modules/home/components/widget/lib/flot-widget.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts index 19f667310b..c976118356 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts @@ -596,13 +596,11 @@ export class TbFlot { } private checkSelectionMode() { - if (this.enableSelection === 'enable') { + if (this.enableSelection === 'enable' || + this.enableSelection === 'mobile' && this.ctx.isMobile || + this.enableSelection === 'desktop' && !this.ctx.isMobile) { this.selectionMode = 'x'; - } else if (this.enableSelection === 'mobile' && this.ctx.isMobile) { - this.selectionMode = 'x'; - } else if (this.enableSelection === 'desktop' && !this.ctx.isMobile) { - this.selectionMode = 'x'; - } else { + } else { this.selectionMode = null; } } From e9a4bb6de2e918c2668a5aa5ff8131ca35ec5114 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Tue, 20 Dec 2022 17:15:29 +0200 Subject: [PATCH 005/207] UI: Fixed widget bundles --- .../src/main/data/json/system/widget_bundles/charts.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/data/json/system/widget_bundles/charts.json b/application/src/main/data/json/system/widget_bundles/charts.json index 452755f083..3910c9ec13 100644 --- a/application/src/main/data/json/system/widget_bundles/charts.json +++ b/application/src/main/data/json/system/widget_bundles/charts.json @@ -196,7 +196,7 @@ "resources": [], "templateHtml": "", "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", - "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'bar');\n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.mobileModeChanged();\n}\n\nself.onLatestDataUpdated = function() {\n self.ctx.flot.latestDataUpdate();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.mobileModeChanged();\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasAdditionalLatestDataKeys: true\n };\n}\n", + "controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'bar');\n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.mobileModeChanged();\n}\n\nself.onLatestDataUpdated = function() {\n self.ctx.flot.latestDataUpdate();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n\nself.typeParameters = function() {\n return {\n hasAdditionalLatestDataKeys: true\n };\n}\n", "settingsSchema": "{}", "dataKeySettingsSchema": "{}", "settingsDirective": "tb-flot-bar-widget-settings", From 30b7d819ec95892817396b33e4512df07a0aad95 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Mon, 20 Feb 2023 16:30:32 +0200 Subject: [PATCH 006/207] enrichment nodes improvements --- .../server/common/data/EntityType.java | 33 ++++++- .../TbAbstractGetEntityDetailsNode.java | 31 +++--- .../metadata/TbGetCustomerDetailsNode.java | 94 +++++++------------ .../metadata/TbGetTenantAttributeNode.java | 1 + .../metadata/TbGetTenantDetailsNode.java | 11 +-- 5 files changed, 86 insertions(+), 84 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java index 4b5bb65bcb..044cc4556f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java @@ -19,5 +19,36 @@ package org.thingsboard.server.common.data; * @author Andrew Shvayka */ public enum EntityType { - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE, TENANT_PROFILE, DEVICE_PROFILE, ASSET_PROFILE, API_USAGE_STATE, TB_RESOURCE, OTA_PACKAGE, EDGE, RPC, QUEUE; + + TENANT("Tenant"), + CUSTOMER("Customer"), + USER("User"), + DASHBOARD("Dashboard"), + ASSET("Asset"), + DEVICE("Device"), + ALARM("Alarm"), + RULE_CHAIN("Rule chain"), + RULE_NODE("Rule node"), + ENTITY_VIEW("Entity view"), + WIDGETS_BUNDLE("Widget bundle"), + WIDGET_TYPE("Widget type"), + TENANT_PROFILE("Tenant profile"), + DEVICE_PROFILE("Device profile"), + ASSET_PROFILE("Asset profile"), + API_USAGE_STATE("Api usage state"), + TB_RESOURCE("TB resource"), + OTA_PACKAGE("OTA package"), + EDGE("Edge"), + RPC("Rpc"), + QUEUE("Queue"); + + private final String displayName; + + EntityType(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java index 928b49318e..c0848f4711 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java @@ -39,7 +39,6 @@ import java.lang.reflect.Type; import java.util.Map; import static org.thingsboard.common.util.DonAsynchron.withCallback; -import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; @Slf4j public abstract class TbAbstractGetEntityDetailsNode implements TbNode { @@ -71,47 +70,47 @@ public abstract class TbAbstractGetEntityDetailsNode getTbMsgListenableFuture(TbContext ctx, TbMsg msg, MessageData messageData, String prefix) { - if (!this.config.getDetailsList().isEmpty()) { + if (this.config.getDetailsList().isEmpty()) { + return Futures.immediateFuture(msg); + } else { ListenableFuture contactBasedListenableFuture = getContactBasedListenableFuture(ctx, msg); ListenableFuture resultObject = addContactProperties(messageData.getData(), contactBasedListenableFuture, prefix); return transformMsg(ctx, msg, resultObject, messageData); - } else { - return Futures.immediateFuture(msg); } } private ListenableFuture transformMsg(TbContext ctx, TbMsg msg, ListenableFuture propertiesFuture, MessageData messageData) { return Futures.transformAsync(propertiesFuture, jsonElement -> { - if (jsonElement != null) { - if (messageData.getDataType().equals("metadata")) { + if (jsonElement == null) { + return Futures.immediateFuture(null); + } else { + if (messageData.getDataSource().equals(DataSource.METADATA)) { Map metadataMap = gson.fromJson(jsonElement.toString(), TYPE); return Futures.immediateFuture(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), new TbMsgMetaData(metadataMap), msg.getData())); } else { return Futures.immediateFuture(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), msg.getMetaData(), gson.toJson(jsonElement))); } - } else { - return Futures.immediateFuture(null); } }, MoreExecutors.directExecutor()); } private ListenableFuture addContactProperties(JsonElement data, ListenableFuture entityFuture, String prefix) { return Futures.transformAsync(entityFuture, contactBased -> { - if (contactBased != null) { + if (contactBased == null) { + return Futures.immediateFuture(null); + } else { JsonElement jsonElement = null; for (EntityDetails entityDetails : this.config.getDetailsList()) { jsonElement = setProperties(contactBased, data, entityDetails, prefix); } return Futures.immediateFuture(jsonElement); - } else { - return Futures.immediateFuture(null); } }, MoreExecutors.directExecutor()); } @@ -175,7 +174,11 @@ public abstract class TbAbstractGetEntityDetailsNode getContactBasedListenableFuture(TbContext ctx, TbMsg msg) { - return Futures.transformAsync(getCustomer(ctx, msg), customer -> { - if (customer != null) { - return Futures.immediateFuture(customer); - } else { - return Futures.immediateFuture(null); - } - }, MoreExecutors.directExecutor()); + return Futures.transformAsync(getCustomer(ctx, msg), customer -> + customer == null ? Futures.immediateFuture(null) : Futures.immediateFuture(customer), + MoreExecutors.directExecutor()); } private ListenableFuture getCustomer(TbContext ctx, TbMsg msg) { switch (msg.getOriginator().getEntityType()) { case DEVICE: - return Futures.transformAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), new DeviceId(msg.getOriginator().getId())), device -> { - if (device != null) { - if (!device.getCustomerId().isNullUid()) { - return ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), device.getCustomerId()); - } else { - throw new RuntimeException("Device with name '" + device.getName() + "' is not assigned to Customer."); - } - } else { - return Futures.immediateFuture(null); - } - }, MoreExecutors.directExecutor()); + return Futures.transformAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), new DeviceId(msg.getOriginator().getId())), + device -> getCustomerFuture(ctx, device, msg.getOriginator()), MoreExecutors.directExecutor()); case ASSET: - return Futures.transformAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), new AssetId(msg.getOriginator().getId())), asset -> { - if (asset != null) { - if (!asset.getCustomerId().isNullUid()) { - return ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), asset.getCustomerId()); - } else { - throw new RuntimeException("Asset with name '" + asset.getName() + "' is not assigned to Customer."); - } - } else { - return Futures.immediateFuture(null); - } - }, MoreExecutors.directExecutor()); + return Futures.transformAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), new AssetId(msg.getOriginator().getId())), + asset -> getCustomerFuture(ctx, asset, msg.getOriginator()), MoreExecutors.directExecutor()); case ENTITY_VIEW: - return Futures.transformAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), new EntityViewId(msg.getOriginator().getId())), entityView -> { - if (entityView != null) { - if (!entityView.getCustomerId().isNullUid()) { - return ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), entityView.getCustomerId()); - } else { - throw new RuntimeException("EntityView with name '" + entityView.getName() + "' is not assigned to Customer."); - } - } else { - return Futures.immediateFuture(null); - } - }, MoreExecutors.directExecutor()); + return Futures.transformAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), new EntityViewId(msg.getOriginator().getId())), + entityView -> getCustomerFuture(ctx, entityView, msg.getOriginator()), MoreExecutors.directExecutor()); case USER: - return Futures.transformAsync(ctx.getUserService().findUserByIdAsync(ctx.getTenantId(), new UserId(msg.getOriginator().getId())), user -> { - if (user != null) { - if (!user.getCustomerId().isNullUid()) { - return ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), user.getCustomerId()); - } else { - throw new RuntimeException("User with name '" + user.getName() + "' is not assigned to Customer."); - } - } else { - return Futures.immediateFuture(null); - } - }, MoreExecutors.directExecutor()); + return Futures.transformAsync(ctx.getUserService().findUserByIdAsync(ctx.getTenantId(), new UserId(msg.getOriginator().getId())), + user -> getCustomerFuture(ctx, user, msg.getOriginator()), MoreExecutors.directExecutor()); case EDGE: - return Futures.transformAsync(ctx.getEdgeService().findEdgeByIdAsync(ctx.getTenantId(), new EdgeId(msg.getOriginator().getId())), edge -> { - if (edge != null) { - if (!edge.getCustomerId().isNullUid()) { - return ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), edge.getCustomerId()); - } else { - throw new RuntimeException("Edge with name '" + edge.getName() + "' is not assigned to Customer."); - } - } else { - return Futures.immediateFuture(null); - } - }, MoreExecutors.directExecutor()); + return Futures.transformAsync(ctx.getEdgeService().findEdgeByIdAsync(ctx.getTenantId(), new EdgeId(msg.getOriginator().getId())), + edge -> getCustomerFuture(ctx, edge, msg.getOriginator()), MoreExecutors.directExecutor()); default: throw new RuntimeException("Entity with entityType '" + msg.getOriginator().getEntityType() + "' is not supported."); } } + private ListenableFuture getCustomerFuture(TbContext ctx, HasCustomerId hasCustomerId, EntityId originator) { + if (hasCustomerId == null) { + return Futures.immediateFuture(null); + } else { + if (hasCustomerId.getCustomerId().isNullUid()) { + if (hasCustomerId instanceof HasName) { + HasName hasName = (HasName) hasCustomerId; + throw new RuntimeException(originator.getEntityType().getDisplayName() + " with name '" + hasName.getName() + "' is not assigned to Customer."); + } + throw new RuntimeException(originator.getEntityType().getDisplayName() + " with id '" + originator + "' is not assigned to Customer."); + } else { + return ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), hasCustomerId.getCustomerId()); + } + } + } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index 7b3f92c0aa..ab422eece8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -40,6 +40,7 @@ public class TbGetTenantAttributeNode extends TbEntityGetAttrNode { @Override protected ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { + ctx.checkTenantEntity(originator); return Futures.immediateFuture(ctx.getTenantId()); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index 2b7316a59b..52c32a5a1e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -54,12 +54,9 @@ public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode getContactBasedListenableFuture(TbContext ctx, TbMsg msg) { - return Futures.transformAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), ctx.getTenantId()), tenant -> { - if (tenant != null) { - return Futures.immediateFuture(tenant); - } else { - return Futures.immediateFuture(null); - } - }, MoreExecutors.directExecutor()); + ctx.checkTenantEntity(msg.getOriginator()); + return Futures.transformAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), ctx.getTenantId()), tenant -> + tenant == null ? Futures.immediateFuture(null) : Futures.immediateFuture(tenant), + MoreExecutors.directExecutor()); } } From 5cfcd1946d493618f297091e5edfdd545c8d257a Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Mon, 20 Feb 2023 16:34:24 +0200 Subject: [PATCH 007/207] merge else if into one for transformMsg method in TbAbstractGetEntityDetailsNode --- .../metadata/TbAbstractGetEntityDetailsNode.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java index c0848f4711..315da5f16a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java @@ -90,13 +90,11 @@ public abstract class TbAbstractGetEntityDetailsNode { if (jsonElement == null) { return Futures.immediateFuture(null); + } else if (messageData.getDataSource().equals(DataSource.METADATA)) { + Map metadataMap = gson.fromJson(jsonElement.toString(), TYPE); + return Futures.immediateFuture(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), new TbMsgMetaData(metadataMap), msg.getData())); } else { - if (messageData.getDataSource().equals(DataSource.METADATA)) { - Map metadataMap = gson.fromJson(jsonElement.toString(), TYPE); - return Futures.immediateFuture(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), new TbMsgMetaData(metadataMap), msg.getData())); - } else { - return Futures.immediateFuture(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), msg.getMetaData(), gson.toJson(jsonElement))); - } + return Futures.immediateFuture(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), msg.getMetaData(), gson.toJson(jsonElement))); } }, MoreExecutors.directExecutor()); } From f29e1f5feff55921339b6f0d34483919039830f3 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 23 Mar 2023 12:44:23 +0200 Subject: [PATCH 008/207] Add fetch to logic, fix and add tests for some rule nodes --- .../rule/engine/api/NodeConfiguration.java | 2 - .../thingsboard/rule/engine/api/TbNode.java | 8 +- .../rule/engine/metadata/FetchTo.java | 21 + .../TbAbstractFetchToNodeConfiguration.java | 23 ++ .../metadata/TbAbstractGetAttributesNode.java | 46 +-- .../metadata/TbAbstractGetEntityAttrNode.java | 110 +++++ .../TbAbstractGetEntityDetailsNode.java | 25 +- ...ractGetEntityDetailsNodeConfiguration.java | 9 +- .../metadata/TbAbstractNodeWithFetchTo.java | 50 +++ .../engine/metadata/TbEntityGetAttrNode.java | 109 ----- .../TbFetchDeviceCredentialsNode.java | 36 +- ...tchDeviceCredentialsNodeConfiguration.java | 9 +- .../engine/metadata/TbGetAttributesNode.java | 15 +- .../TbGetAttributesNodeConfiguration.java | 9 +- .../metadata/TbGetCustomerAttributeNode.java | 17 +- .../metadata/TbGetCustomerDetailsNode.java | 5 +- ...TbGetCustomerDetailsNodeConfiguration.java | 5 +- .../engine/metadata/TbGetDeviceAttrNode.java | 5 +- .../TbGetDeviceAttrNodeConfiguration.java | 5 +- .../TbGetEntityAttrNodeConfiguration.java | 7 +- .../TbGetOriginatorFieldsConfiguration.java | 6 +- .../metadata/TbGetOriginatorFieldsNode.java | 80 ++-- .../TbGetRelatedAttrNodeConfiguration.java | 3 +- .../metadata/TbGetRelatedAttributeNode.java | 25 +- .../metadata/TbGetTenantAttributeNode.java | 18 +- .../metadata/TbGetTenantDetailsNode.java | 4 +- .../TbGetTenantDetailsNodeConfiguration.java | 5 +- .../util/EntitiesFieldsAsyncLoader.java | 42 +- ....java => TbAbstractAttributeNodeTest.java} | 20 +- .../TbAbstractGetAttributesNodeTest.java | 58 +-- .../TbFetchDeviceCredentialsNodeTest.java | 6 +- .../TbGetCustomerAttributeNodeTest.java | 81 +++- .../TbGetOriginatorFieldsNodeTest.java | 376 ++++++++++++++++++ .../TbGetRelatedAttributeNodeTest.java | 83 +++- .../TbGetTenantAttributeNodeTest.java | 85 +++- .../util/EntitiesFieldsAsyncLoaderTest.java | 231 +++++++++++ .../rule/engine/util/TenantIdLoaderTest.java | 7 +- 37 files changed, 1277 insertions(+), 369 deletions(-) create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/FetchTo.java create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java delete mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbEntityGetAttrNode.java rename rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/{AbstractAttributeNodeTest.java => TbAbstractAttributeNodeTest.java} (96%) create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NodeConfiguration.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NodeConfiguration.java index 12a25b517c..8c11ddc110 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NodeConfiguration.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NodeConfiguration.java @@ -16,7 +16,5 @@ package org.thingsboard.rule.engine.api; public interface NodeConfiguration { - T defaultConfiguration(); - } diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java index 18044eb05c..a0fbdaf8e1 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java @@ -24,13 +24,13 @@ import java.util.concurrent.ExecutionException; * Created by ashvayka on 19.01.18. */ public interface TbNode { - void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException; void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException; - default void destroy() {} - - default void onPartitionChangeMsg(TbContext ctx, PartitionChangeMsg msg) {} + default void destroy() { + } + default void onPartitionChangeMsg(TbContext ctx, PartitionChangeMsg msg) { + } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/FetchTo.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/FetchTo.java new file mode 100644 index 0000000000..dcd8c81477 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/FetchTo.java @@ -0,0 +1,21 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +public enum FetchTo { + DATA, + METADATA +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java new file mode 100644 index 0000000000..63ddf9be5f --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java @@ -0,0 +1,23 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +import lombok.Data; + +@Data +public abstract class TbAbstractFetchToNodeConfiguration { + private FetchTo fetchTo; +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java index e5ef68e421..378e7d1358 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java @@ -22,10 +22,8 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.BooleanUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; @@ -53,26 +51,19 @@ import static org.thingsboard.server.common.data.DataConstants.LATEST_TS; import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE; -public abstract class TbAbstractGetAttributesNode implements TbNode { - +public abstract class TbAbstractGetAttributesNode extends TbAbstractNodeWithFetchTo { private static final String VALUE = "value"; private static final String TS = "ts"; - - protected C config; - private boolean fetchToData; private boolean isTellFailureIfAbsent; private boolean getLatestValueWithTs; @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.config = loadGetAttributesNodeConfig(configuration); - this.fetchToData = config.isFetchToData(); - this.getLatestValueWithTs = config.isGetLatestValueWithTs(); - this.isTellFailureIfAbsent = BooleanUtils.toBooleanDefaultIfNull(this.config.isTellFailureIfAbsent(), true); + super.init(ctx, configuration); + getLatestValueWithTs = config.isGetLatestValueWithTs(); + isTellFailureIfAbsent = config.isTellFailureIfAbsent(); } - protected abstract C loadGetAttributesNodeConfig(TbNodeConfiguration configuration) throws TbNodeException; - @Override public void onMsg(TbContext ctx, TbMsg msg) throws TbNodeException { try { @@ -92,13 +83,9 @@ public abstract class TbAbstractGetAttributesNode { String key = prefix + kvEntry.getKey(); - if (fetchToData) { - JacksonUtil.addKvEntry((ObjectNode) msgDataNode, kvEntry, key); - } else { + if (FetchTo.DATA.equals(fetchTo)) { + JacksonUtil.addKvEntry(msgDataNode, kvEntry, key); + } else if (FetchTo.METADATA.equals(fetchTo)) { msgMetaData.putValue(key, kvEntry.getValueAsString()); } }); }); }); - TbMsg outMsg = fetchToData ? - TbMsg.transformMsgData(msg, JacksonUtil.toString(msgDataNode)) : - TbMsg.transformMsg(msg, msgMetaData); + + TbMsg outMsg = null; + if (FetchTo.DATA.equals(fetchTo)) { + outMsg = TbMsg.transformMsgData(msg, JacksonUtil.toString(msgDataNode)); + } else if (FetchTo.METADATA.equals(fetchTo)) { + outMsg = TbMsg.transformMsg(msg, msgMetaData); + } + if (failuresMap.isEmpty()) { ctx.tellSuccess(outMsg); } else { @@ -175,7 +167,7 @@ public abstract class TbAbstractGetAttributesNode extends TbAbstractNodeWithFetchTo { + @Override + public void onMsg(TbContext ctx, TbMsg msg) { + ObjectNode msgDataAsJsonNode; + if (FetchTo.DATA.equals(fetchTo)) { + msgDataAsJsonNode = getMsgDataAsObjectNode(msg); + } else { + msgDataAsJsonNode = null; + } + ctx.checkTenantEntity(msg.getOriginator()); + withCallback(findEntityAsync(ctx, msg.getOriginator()), + entityId -> safeGetAttributes(ctx, msg, entityId, msgDataAsJsonNode), + t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); + } + + protected abstract ListenableFuture findEntityAsync(TbContext ctx, EntityId originator); + + private void safeGetAttributes(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) { + if (entityId == null || entityId.isNullUid()) { + ctx.tellNext(msg, FAILURE); + return; + } + + Map mappingsMap = new HashMap<>(); + config.getAttrMapping().forEach((key, value) -> { + String patternProcessedSourceKey = TbNodeUtils.processPattern(key, msg); + String patternProcessedTargetKey = TbNodeUtils.processPattern(value, msg); + mappingsMap.put(patternProcessedSourceKey, patternProcessedTargetKey); + }); + + var sourceKeys = List.copyOf(mappingsMap.keySet()); + withCallback(config.isTelemetry() ? getLatestTelemetryAsync(ctx, entityId, sourceKeys) : getAttributesAsync(ctx, entityId, sourceKeys), + data -> putDataAndTell(ctx, msg, data, mappingsMap, msgDataAsJsonNode), + t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); + } + + private ListenableFuture> getAttributesAsync(TbContext ctx, EntityId entityId, List attrKeys) { + var latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, attrKeys); + return Futures.transform(latest, l -> + l.stream() + .map(i -> (KvEntry) i) + .collect(Collectors.toList()), + MoreExecutors.directExecutor()); + } + + private ListenableFuture> getLatestTelemetryAsync(TbContext ctx, EntityId entityId, List timeseriesKeys) { + var latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, timeseriesKeys); + return Futures.transform(latest, l -> + l.stream() + .map(i -> (KvEntry) i) + .collect(Collectors.toList()), + MoreExecutors.directExecutor()); + } + + private void putDataAndTell(TbContext ctx, TbMsg msg, List data, Map map, ObjectNode msgDataAsJsonNode) { + for (KvEntry entry : data) { + String targetKey = map.get(entry.getKey()); + String value = entry.getValueAsString(); + if (FetchTo.DATA.equals(fetchTo)) { + msgDataAsJsonNode.put(targetKey, value); + } else if (FetchTo.METADATA.equals(fetchTo)) { + msg.getMetaData().putValue(targetKey, value); + } + } + if (FetchTo.DATA.equals(fetchTo)) { + ctx.tellSuccess(TbMsg.transformMsgData(msg, JacksonUtil.toString(msgDataAsJsonNode))); + } else if (FetchTo.METADATA.equals(fetchTo)) { + ctx.tellSuccess(msg); + } + } +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java index 315da5f16a..21918029ef 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java @@ -27,11 +27,9 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.rule.engine.api.TbNode; -import org.thingsboard.rule.engine.api.TbNodeConfiguration; -import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.util.EntityDetails; import org.thingsboard.server.common.data.ContactBased; +import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -41,20 +39,11 @@ import java.util.Map; import static org.thingsboard.common.util.DonAsynchron.withCallback; @Slf4j -public abstract class TbAbstractGetEntityDetailsNode implements TbNode { - +public abstract class TbAbstractGetEntityDetailsNode extends TbAbstractNodeWithFetchTo { private static final Gson gson = new Gson(); - private static final JsonParser jsonParser = new JsonParser(); private static final Type TYPE = new TypeToken>() { }.getType(); - protected C config; - - @Override - public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.config = loadGetEntityDetailsNodeConfiguration(configuration); - } - @Override public void onMsg(TbContext ctx, TbMsg msg) { withCallback(getDetails(ctx, msg), @@ -62,22 +51,20 @@ public abstract class TbAbstractGetEntityDetailsNode ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); } - protected abstract C loadGetEntityDetailsNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException; - protected abstract ListenableFuture getDetails(TbContext ctx, TbMsg msg); protected abstract ListenableFuture getContactBasedListenableFuture(TbContext ctx, TbMsg msg); protected MessageData getDataAsJson(TbMsg msg) { - if (this.config.isAddToMetadata()) { + if (config.getFetchTo() == FetchTo.METADATA) { return new MessageData(gson.toJsonTree(msg.getMetaData().getData(), TYPE), DataSource.METADATA); } else { - return new MessageData(jsonParser.parse(msg.getData()), DataSource.DATA); + return new MessageData(JsonParser.parseString(msg.getData()), DataSource.DATA); } } protected ListenableFuture getTbMsgListenableFuture(TbContext ctx, TbMsg msg, MessageData messageData, String prefix) { - if (this.config.getDetailsList().isEmpty()) { + if (config.getDetailsList().isEmpty()) { return Futures.immediateFuture(msg); } else { ListenableFuture contactBasedListenableFuture = getContactBasedListenableFuture(ctx, msg); @@ -178,6 +165,4 @@ public abstract class TbAbstractGetEntityDetailsNode detailsList; - - private boolean addToMetadata; - } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java new file mode 100644 index 0000000000..3cf6300b77 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java @@ -0,0 +1,50 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNode; +import org.thingsboard.rule.engine.api.TbNodeConfiguration; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.msg.TbMsg; + +public abstract class TbAbstractNodeWithFetchTo implements TbNode { + protected C config; + protected FetchTo fetchTo; + + @Override + public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { + config = loadNodeConfiguration(configuration); + if (config.getFetchTo() == null) { + throw new TbNodeException("FetchTo cannot be NULL!"); + } else { + fetchTo = config.getFetchTo(); + } + } + + protected abstract C loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException; + + protected ObjectNode getMsgDataAsObjectNode(TbMsg msg) { + JsonNode msgDataNode = JacksonUtil.toJsonNode(msg.getData()); + if (!msgDataNode.isObject()) { + throw new IllegalArgumentException("Message body is not an object!"); + } + return (ObjectNode) msgDataNode; + } +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbEntityGetAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbEntityGetAttrNode.java deleted file mode 100644 index 8031939c7d..0000000000 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbEntityGetAttrNode.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.rule.engine.metadata; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; -import lombok.extern.slf4j.Slf4j; -import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.rule.engine.api.TbNode; -import org.thingsboard.rule.engine.api.TbNodeConfiguration; -import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.rule.engine.api.util.TbNodeUtils; -import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.kv.AttributeKvEntry; -import org.thingsboard.server.common.data.kv.KvEntry; -import org.thingsboard.server.common.data.kv.TsKvEntry; -import org.thingsboard.server.common.msg.TbMsg; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static org.thingsboard.common.util.DonAsynchron.withCallback; -import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE; -import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; - -@Slf4j -public abstract class TbEntityGetAttrNode implements TbNode { - - private TbGetEntityAttrNodeConfiguration config; - - @Override - public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.config = TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); - } - - @Override - public void onMsg(TbContext ctx, TbMsg msg) { - try { - withCallback(findEntityAsync(ctx, msg.getOriginator()), - entityId -> safeGetAttributes(ctx, msg, entityId), - t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); - } catch (Throwable th) { - ctx.tellFailure(msg, th); - } - } - - private void safeGetAttributes(TbContext ctx, TbMsg msg, T entityId) { - if (entityId == null || entityId.isNullUid()) { - ctx.tellNext(msg, FAILURE); - return; - } - - Map mappingsMap = new HashMap<>(); - config.getAttrMapping().forEach((key, value) -> { - String processPatternKey = TbNodeUtils.processPattern(key, msg); - String processPatternValue = TbNodeUtils.processPattern(value, msg); - mappingsMap.put(processPatternKey, processPatternValue); - }); - - List keys = List.copyOf(mappingsMap.keySet()); - withCallback(config.isTelemetry() ? getLatestTelemetry(ctx, entityId, keys) : getAttributesAsync(ctx, entityId, keys), - attributes -> putAttributesAndTell(ctx, msg, attributes, mappingsMap), - t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); - } - - private ListenableFuture> getAttributesAsync(TbContext ctx, EntityId entityId, List attrKeys) { - ListenableFuture> latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, attrKeys); - return Futures.transform(latest, l -> - l.stream().map(i -> (KvEntry) i).collect(Collectors.toList()), MoreExecutors.directExecutor()); - } - - private ListenableFuture> getLatestTelemetry(TbContext ctx, EntityId entityId, List timeseriesKeys) { - ListenableFuture> latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, timeseriesKeys); - return Futures.transform(latest, l -> - l.stream().map(i -> (KvEntry) i).collect(Collectors.toList()), MoreExecutors.directExecutor()); - } - - - private void putAttributesAndTell(TbContext ctx, TbMsg msg, List attributes, Map map) { - attributes.forEach(r -> { - String attrName = map.get(r.getKey()); - msg.getMetaData().putValue(attrName, r.getValueAsString()); - }); - ctx.tellSuccess(msg); - } - - protected abstract ListenableFuture findEntityAsync(TbContext ctx, EntityId originator); - - public void setConfig(TbGetEntityAttrNodeConfiguration config) { - this.config = config; - } - -} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java index 2aa3b7a837..abded26923 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java @@ -15,24 +15,19 @@ */ package org.thingsboard.rule.engine.metadata; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.plugin.ComponentType; -import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.msg.TbMsg; -import org.thingsboard.server.common.msg.TbMsgMetaData; import java.util.concurrent.ExecutionException; @@ -48,39 +43,36 @@ import java.util.concurrent.ExecutionException; "- send Message via Failure chain, otherwise Success chain is used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeFetchDeviceCredentialsConfig") -public class TbFetchDeviceCredentialsNode implements TbNode { - +public class TbFetchDeviceCredentialsNode extends TbAbstractNodeWithFetchTo { private static final String CREDENTIALS = "credentials"; private static final String CREDENTIALS_TYPE = "credentialsType"; - TbFetchDeviceCredentialsNodeConfiguration config; - boolean fetchToMetadata; - @Override - public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.config = TbNodeUtils.convert(configuration, TbFetchDeviceCredentialsNodeConfiguration.class); - this.fetchToMetadata = config.isFetchToMetadata(); + protected TbFetchDeviceCredentialsNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + return TbNodeUtils.convert(configuration, TbFetchDeviceCredentialsNodeConfiguration.class); } @Override public void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException { - EntityId originator = msg.getOriginator(); + var originator = msg.getOriginator(); if (!EntityType.DEVICE.equals(originator.getEntityType())) { ctx.tellFailure(msg, new RuntimeException("Unsupported originator type: " + originator.getEntityType() + "!")); return; } - DeviceId deviceId = new DeviceId(msg.getOriginator().getId()); - DeviceCredentials deviceCredentials = ctx.getDeviceCredentialsService().findDeviceCredentialsByDeviceId(ctx.getTenantId(), deviceId); + + var deviceId = new DeviceId(msg.getOriginator().getId()); + var deviceCredentials = ctx.getDeviceCredentialsService().findDeviceCredentialsByDeviceId(ctx.getTenantId(), deviceId); if (deviceCredentials == null) { ctx.tellFailure(msg, new RuntimeException("Failed to get Device Credentials for device: " + deviceId + "!")); return; } - TbMsg transformedMsg; - DeviceCredentialsType credentialsType = deviceCredentials.getCredentialsType(); - JsonNode credentialsInfo = ctx.getDeviceCredentialsService().toCredentialsInfo(deviceCredentials); - if (fetchToMetadata) { - TbMsgMetaData metaData = msg.getMetaData(); + TbMsg transformedMsg = null; + var credentialsType = deviceCredentials.getCredentialsType(); + var credentialsInfo = ctx.getDeviceCredentialsService().toCredentialsInfo(deviceCredentials); + + if (FetchTo.METADATA.equals(fetchTo)) { + var metaData = msg.getMetaData(); metaData.putValue(CREDENTIALS_TYPE, credentialsType.name()); if (credentialsType.equals(DeviceCredentialsType.ACCESS_TOKEN) || credentialsType.equals(DeviceCredentialsType.X509_CERTIFICATE)) { metaData.putValue(CREDENTIALS, credentialsInfo.asText()); @@ -88,7 +80,7 @@ public class TbFetchDeviceCredentialsNode implements TbNode { metaData.putValue(CREDENTIALS, JacksonUtil.toString(credentialsInfo)); } transformedMsg = TbMsg.transformMsg(msg, msg.getType(), originator, metaData, msg.getData()); - } else { + } else if (FetchTo.DATA.equals(fetchTo)) { ObjectNode data = (ObjectNode) JacksonUtil.toJsonNode(msg.getData()); data.put(CREDENTIALS_TYPE, credentialsType.name()); data.set(CREDENTIALS, credentialsInfo); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeConfiguration.java index 66fddb0770..5f8b5921f8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeConfiguration.java @@ -17,18 +17,17 @@ package org.thingsboard.rule.engine.metadata; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; @Data +@EqualsAndHashCode(callSuper = true) @JsonIgnoreProperties(ignoreUnknown = true) -public class TbFetchDeviceCredentialsNodeConfiguration implements NodeConfiguration { - - private boolean fetchToMetadata; - +public class TbFetchDeviceCredentialsNodeConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { @Override public TbFetchDeviceCredentialsNodeConfiguration defaultConfiguration() { TbFetchDeviceCredentialsNodeConfiguration configuration = new TbFetchDeviceCredentialsNodeConfiguration(); - configuration.setFetchToMetadata(true); + configuration.setFetchTo(FetchTo.METADATA); return configuration; } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index 7e42105e5d..0cd8b9cade 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -32,25 +32,24 @@ import org.thingsboard.server.common.msg.TbMsg; */ @Slf4j @RuleNode(type = ComponentType.ENRICHMENT, - name = "originator attributes", - configClazz = TbGetAttributesNodeConfiguration.class, - nodeDescription = "Enrich the message body or metadata with the originator attributes and/or timeseries data", - nodeDetails = "If Attributes enrichment configured, CLIENT/SHARED/SERVER attributes are added into Message data/metadata " + + name = "originator attributes", + configClazz = TbGetAttributesNodeConfiguration.class, + nodeDescription = "Enrich the message body or metadata with the originator attributes and/or timeseries data", + nodeDetails = "If Attributes enrichment configured, CLIENT/SHARED/SERVER attributes are added into Message data/metadata " + "with specific prefix: cs/shared/ss. Latest telemetry value added into Message data/metadata without prefix. " + - "To access those attributes in other nodes this template can be used " + + "To access those attributes in other nodes this template can be used " + "metadata.cs_temperature or metadata.shared_limit ", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeOriginatorAttributesConfig") public class TbGetAttributesNode extends TbAbstractGetAttributesNode { - @Override - protected TbGetAttributesNodeConfiguration loadGetAttributesNodeConfig(TbNodeConfiguration configuration) throws TbNodeException { + protected TbGetAttributesNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { return TbNodeUtils.convert(configuration, TbGetAttributesNodeConfiguration.class); } @Override protected ListenableFuture findEntityIdAsync(TbContext ctx, TbMsg msg) { + ctx.checkTenantEntity(msg.getOriginator()); return Futures.immediateFuture(msg.getOriginator()); } - } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java index e587fb9c7a..7c2b515668 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java @@ -16,8 +16,8 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; - import java.util.Collections; import java.util.List; @@ -25,8 +25,8 @@ import java.util.List; * Created by ashvayka on 19.01.18. */ @Data -public class TbGetAttributesNodeConfiguration implements NodeConfiguration { - +@EqualsAndHashCode(callSuper = true) +public class TbGetAttributesNodeConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { private List clientAttributeNames; private List sharedAttributeNames; private List serverAttributeNames; @@ -35,7 +35,6 @@ public class TbGetAttributesNodeConfiguration implements NodeConfiguration" + "Useful when you store some parameters on the customer level and would like to use them for message processing.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeCustomerAttributesConfig") -public class TbGetCustomerAttributeNode extends TbEntityGetAttrNode { - +public class TbGetCustomerAttributeNode extends TbAbstractGetEntityAttrNode { @Override protected ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { + ctx.checkTenantEntity(originator); return EntitiesCustomerIdAsyncLoader.findEntityIdAsync(ctx, originator); } + @Override + protected TbGetEntityAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + return TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); + } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index 3afc66c4dc..cdcf522876 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; +import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; @@ -48,16 +49,16 @@ import org.thingsboard.server.common.msg.TbMsg; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeEntityDetailsConfig") public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode { - private static final String CUSTOMER_PREFIX = "customer_"; @Override - protected TbGetCustomerDetailsNodeConfiguration loadGetEntityDetailsNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + protected TbGetCustomerDetailsNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { return TbNodeUtils.convert(configuration, TbGetCustomerDetailsNodeConfiguration.class); } @Override protected ListenableFuture getDetails(TbContext ctx, TbMsg msg) { + ctx.checkTenantEntity(msg.getOriginator()); return getTbMsgListenableFuture(ctx, msg, getDataAsJson(msg), CUSTOMER_PREFIX); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeConfiguration.java index 0d74d49942..91587e18f2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeConfiguration.java @@ -16,18 +16,19 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; import java.util.Collections; @Data +@EqualsAndHashCode(callSuper = true) public class TbGetCustomerDetailsNodeConfiguration extends TbAbstractGetEntityDetailsNodeConfiguration implements NodeConfiguration { - - @Override public TbGetCustomerDetailsNodeConfiguration defaultConfiguration() { TbGetCustomerDetailsNodeConfiguration configuration = new TbGetCustomerDetailsNodeConfiguration(); configuration.setDetailsList(Collections.emptyList()); + configuration.setFetchTo(FetchTo.METADATA); return configuration; } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java index b0a221e46e..96230ae28f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java @@ -39,15 +39,14 @@ import org.thingsboard.server.common.msg.TbMsg; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeDeviceAttributesConfig") public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode { - @Override - protected TbGetDeviceAttrNodeConfiguration loadGetAttributesNodeConfig(TbNodeConfiguration configuration) throws TbNodeException { + protected TbGetDeviceAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { return TbNodeUtils.convert(configuration, TbGetDeviceAttrNodeConfiguration.class); } @Override protected ListenableFuture findEntityIdAsync(TbContext ctx, TbMsg msg) { + ctx.checkTenantEntity(msg.getOriginator()); return EntitiesRelatedDeviceIdAsyncLoader.findDeviceAsync(ctx, msg.getOriginator(), config.getDeviceRelationsQuery()); } - } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java index ac5b98134a..f3ba3651cc 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java @@ -16,6 +16,7 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.data.DeviceRelationsQuery; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; @@ -23,8 +24,8 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; import java.util.Collections; @Data +@EqualsAndHashCode(callSuper = true) public class TbGetDeviceAttrNodeConfiguration extends TbGetAttributesNodeConfiguration { - private DeviceRelationsQuery deviceRelationsQuery; @Override @@ -36,7 +37,7 @@ public class TbGetDeviceAttrNodeConfiguration extends TbGetAttributesNodeConfigu configuration.setLatestTsKeyNames(Collections.emptyList()); configuration.setTellFailureIfAbsent(true); configuration.setGetLatestValueWithTs(false); - configuration.setFetchToData(false); + configuration.setFetchTo(FetchTo.METADATA); DeviceRelationsQuery deviceRelationsQuery = new DeviceRelationsQuery(); deviceRelationsQuery.setDirection(EntitySearchDirection.FROM); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java index be2eab5bb0..12a94e227f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java @@ -16,15 +16,15 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; import java.util.HashMap; import java.util.Map; -import java.util.Optional; @Data -public class TbGetEntityAttrNodeConfiguration implements NodeConfiguration { - +@EqualsAndHashCode(callSuper = true) +public class TbGetEntityAttrNodeConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { private Map attrMapping; private boolean isTelemetry = false; @@ -35,6 +35,7 @@ public class TbGetEntityAttrNodeConfiguration implements NodeConfiguration { - +@EqualsAndHashCode(callSuper = true) +public class TbGetOriginatorFieldsConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { private Map fieldsMapping; private boolean ignoreNullStrings; @@ -35,6 +36,7 @@ public class TbGetOriginatorFieldsConfiguration implements NodeConfiguration { @Override - public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - config = TbNodeUtils.convert(configuration, TbGetOriginatorFieldsConfiguration.class); - ignoreNullStrings = config.isIgnoreNullStrings(); + protected TbGetOriginatorFieldsConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + return TbNodeUtils.convert(configuration, TbGetOriginatorFieldsConfiguration.class); } @Override public void onMsg(TbContext ctx, TbMsg msg) { - try { - withCallback(putEntityFields(ctx, msg.getOriginator(), msg), - i -> ctx.tellSuccess(msg), t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); - } catch (Throwable th) { - ctx.tellFailure(msg, th); + ObjectNode msgDataAsJsonNode; + if (FetchTo.DATA.equals(fetchTo)) { + msgDataAsJsonNode = getMsgDataAsObjectNode(msg); + } else { + msgDataAsJsonNode = null; } + ctx.checkTenantEntity(msg.getOriginator()); + withCallback(collectMappedEntityFieldsAsync(ctx, msg.getOriginator()), + targetKeysToSourceValuesMap -> { + for (var entry : targetKeysToSourceValuesMap.entrySet()) { + var targetKeyName = entry.getKey(); + var sourceFieldValue = entry.getValue(); + if (FetchTo.DATA.equals(fetchTo)) { + msgDataAsJsonNode.put(targetKeyName, sourceFieldValue); + } else if (FetchTo.METADATA.equals(fetchTo)) { + msg.getMetaData().putValue(targetKeyName, sourceFieldValue); + } + } + + if (FetchTo.DATA.equals(fetchTo)) { + ctx.tellSuccess(TbMsg.transformMsgData(msg, JacksonUtil.toString(msgDataAsJsonNode))); + } else if (FetchTo.METADATA.equals(fetchTo)) { + ctx.tellSuccess(msg); + } + }, + t -> ctx.tellFailure(msg, t), + MoreExecutors.directExecutor()); } - private ListenableFuture putEntityFields(TbContext ctx, EntityId entityId, TbMsg msg) { + private ListenableFuture> collectMappedEntityFieldsAsync(TbContext ctx, EntityId entityId) { if (config.getFieldsMapping().isEmpty()) { - return Futures.immediateFuture(null); + return Futures.immediateFuture(Collections.emptyMap()); } else { return Futures.transform(EntitiesFieldsAsyncLoader.findAsync(ctx, entityId), - data -> { - config.getFieldsMapping().forEach((field, metaKey) -> { - String val = data.getFieldValue(field, ignoreNullStrings); - if (val != null) { - msg.getMetaData().putValue(metaKey, val); + fieldsData -> { + var targetKeysToSourceValuesMap = new HashMap(); + for (var mappingEntry : config.getFieldsMapping().entrySet()) { + var sourceFieldName = mappingEntry.getKey(); + var targetKeyName = mappingEntry.getValue(); + var sourceFieldValue = fieldsData.getFieldValue(sourceFieldName, config.isIgnoreNullStrings()); + if (sourceFieldValue != null) { + targetKeysToSourceValuesMap.put(targetKeyName, sourceFieldValue); } - }); - return null; - }, MoreExecutors.directExecutor() + } + return targetKeysToSourceValuesMap; + }, ctx.getDbCallbackExecutor() ); } } - } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java index 489e04f60e..8df69c67af 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java @@ -16,6 +16,7 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.data.RelationsQuery; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; @@ -26,8 +27,8 @@ import java.util.HashMap; import java.util.Map; @Data +@EqualsAndHashCode(callSuper = true) public class TbGetRelatedAttrNodeConfiguration extends TbGetEntityAttrNodeConfiguration { - private RelationsQuery relationsQuery; @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index b7ef24f36b..d722d1c62b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -27,30 +27,27 @@ import org.thingsboard.server.common.data.plugin.ComponentType; @RuleNode( type = ComponentType.ENRICHMENT, - name="related attributes", + name = "related attributes", configClazz = TbGetRelatedAttrNodeConfiguration.class, - nodeDescription = "Add Originators Related Entity Attributes or Latest Telemetry into Message Metadata", + nodeDescription = "Add Originators Related Entity Attributes or Latest Telemetry into Message Metadata/Data", nodeDetails = "Related Entity found using configured relation direction and Relation Type. " + "If multiple Related Entities are found, only first Entity is used for attributes enrichment, other entities are discarded. " + - "If Attributes enrichment configured, server scope attributes are added into Message metadata. " + - "If Latest Telemetry enrichment configured, latest telemetry added into metadata. " + + "If Attributes enrichment configured, server scope attributes are added into Message Metadata/Data. " + + "If Latest Telemetry enrichment configured, latest telemetry added into Metadata/Data. " + "To access those attributes in other nodes this template can be used " + "metadata.temperature.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeRelatedAttributesConfig") - -public class TbGetRelatedAttributeNode extends TbEntityGetAttrNode { - - private TbGetRelatedAttrNodeConfiguration config; - +public class TbGetRelatedAttributeNode extends TbAbstractGetEntityAttrNode { @Override - public void init(TbContext context, TbNodeConfiguration configuration) throws TbNodeException { - this.config = TbNodeUtils.convert(configuration, TbGetRelatedAttrNodeConfiguration.class); - setConfig(config); + public TbGetRelatedAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + return TbNodeUtils.convert(configuration, TbGetRelatedAttrNodeConfiguration.class); } @Override - protected ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { - return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, originator, config.getRelationsQuery()); + public ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { + ctx.checkTenantEntity(originator); + var relatedAttrConfig = (TbGetRelatedAttrNodeConfiguration) config; + return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, originator, relatedAttrConfig.getRelationsQuery()); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index ab422eece8..87b60dfdaf 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -20,6 +20,9 @@ import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNodeConfiguration; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentType; @@ -29,19 +32,22 @@ import org.thingsboard.server.common.data.plugin.ComponentType; type = ComponentType.ENRICHMENT, name="tenant attributes", configClazz = TbGetEntityAttrNodeConfiguration.class, - nodeDescription = "Add Originators Tenant Attributes or Latest Telemetry into Message Metadata", - nodeDetails = "If Attributes enrichment configured, server scope attributes are added into Message metadata. " + - "If Latest Telemetry enrichment configured, latest telemetry added into metadata. " + + nodeDescription = "Add Originators Tenant Attributes or Latest Telemetry into Message Metadata/Data", + nodeDetails = "If Attributes enrichment configured, server scope attributes are added into Message Metadata/Data. " + + "If Latest Telemetry enrichment configured, latest telemetry added into Metadata/Data. " + "To access those attributes in other nodes this template can be used " + "metadata.temperature.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeTenantAttributesConfig") -public class TbGetTenantAttributeNode extends TbEntityGetAttrNode { - +public class TbGetTenantAttributeNode extends TbAbstractGetEntityAttrNode { @Override - protected ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { + public ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { ctx.checkTenantEntity(originator); return Futures.immediateFuture(ctx.getTenantId()); } + @Override + public TbGetEntityAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + return TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); + } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index 52c32a5a1e..983b17e61e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -25,6 +25,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.ContactBased; +import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; @@ -39,11 +40,10 @@ import org.thingsboard.server.common.msg.TbMsg; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeEntityDetailsConfig") public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode { - private static final String TENANT_PREFIX = "tenant_"; @Override - protected TbGetTenantDetailsNodeConfiguration loadGetEntityDetailsNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + protected TbGetTenantDetailsNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { return TbNodeUtils.convert(configuration, TbGetTenantDetailsNodeConfiguration.class); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeConfiguration.java index 7770d6acb1..e3608abbbd 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeConfiguration.java @@ -16,18 +16,19 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; +import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; import java.util.Collections; @Data +@EqualsAndHashCode(callSuper = true) public class TbGetTenantDetailsNodeConfiguration extends TbAbstractGetEntityDetailsNodeConfiguration implements NodeConfiguration { - - @Override public TbGetTenantDetailsNodeConfiguration defaultConfiguration() { TbGetTenantDetailsNodeConfiguration configuration = new TbGetTenantDetailsNodeConfiguration(); configuration.setDetailsList(Collections.emptyList()); + configuration.setFetchTo(FetchTo.METADATA); return configuration; } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java index cb9ee7c8b6..9d78005e23 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,6 +18,7 @@ package org.thingsboard.rule.engine.util; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; +import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.BaseData; @@ -30,47 +31,50 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UserId; import java.util.function.Function; +@Slf4j public class EntitiesFieldsAsyncLoader { - - public static ListenableFuture findAsync(TbContext ctx, EntityId original) { - switch (original.getEntityType()) { + public static ListenableFuture findAsync(TbContext ctx, EntityId originatorId) { + switch (originatorId.getEntityType()) { case TENANT: - return getAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), (TenantId) original), + return toEntityFieldsDataAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), (TenantId) originatorId), EntityFieldsData::new); case CUSTOMER: - return getAsync(ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), (CustomerId) original), + return toEntityFieldsDataAsync(ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), (CustomerId) originatorId), EntityFieldsData::new); case USER: - return getAsync(ctx.getUserService().findUserByIdAsync(ctx.getTenantId(), (UserId) original), + return toEntityFieldsDataAsync(ctx.getUserService().findUserByIdAsync(ctx.getTenantId(), (UserId) originatorId), EntityFieldsData::new); case ASSET: - return getAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), (AssetId) original), + return toEntityFieldsDataAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), (AssetId) originatorId), EntityFieldsData::new); case DEVICE: - return getAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), (DeviceId) original), + return toEntityFieldsDataAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), (DeviceId) originatorId), EntityFieldsData::new); case ALARM: - return getAsync(ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), (AlarmId) original), + return toEntityFieldsDataAsync(ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), (AlarmId) originatorId), EntityFieldsData::new); case RULE_CHAIN: - return getAsync(ctx.getRuleChainService().findRuleChainByIdAsync(ctx.getTenantId(), (RuleChainId) original), + return toEntityFieldsDataAsync(ctx.getRuleChainService().findRuleChainByIdAsync(ctx.getTenantId(), (RuleChainId) originatorId), EntityFieldsData::new); case ENTITY_VIEW: - return getAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), (EntityViewId) original), + return toEntityFieldsDataAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), (EntityViewId) originatorId), EntityFieldsData::new); default: - return Futures.immediateFailedFuture(new TbNodeException("Unexpected original EntityType " + original.getEntityType())); + return Futures.immediateFailedFuture(new TbNodeException("Unexpected originator EntityType: " + originatorId.getEntityType())); } } - private static ListenableFuture getAsync( - ListenableFuture future, Function converter) { + private static > ListenableFuture toEntityFieldsDataAsync( + ListenableFuture future, + Function converter + ) { return Futures.transformAsync(future, in -> in != null ? Futures.immediateFuture(converter.apply(in)) - : Futures.immediateFailedFuture(new RuntimeException("Entity not found!")), MoreExecutors.directExecutor()); + : Futures.immediateFailedFuture(new TbNodeException("Entity not found!")), MoreExecutors.directExecutor()); } } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/AbstractAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java similarity index 96% rename from rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/AbstractAttributeNodeTest.java rename to rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java index 45e4f1c27f..a3949587b9 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/AbstractAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -65,7 +65,7 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE; import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; @RunWith(MockitoJUnitRunner.class) -public abstract class AbstractAttributeNodeTest { +public abstract class TbAbstractAttributeNodeTest { final CustomerId customerId = new CustomerId(Uuids.timeBased()); final TenantId tenantId = TenantId.fromUUID(Uuids.timeBased()); final RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased()); @@ -86,9 +86,9 @@ public abstract class AbstractAttributeNodeTest { DeviceService deviceService; TbMsg msg; Map metaData; - TbEntityGetAttrNode node; + TbAbstractGetEntityAttrNode node; - void init(TbEntityGetAttrNode node) throws TbNodeException { + void init(TbAbstractGetEntityAttrNode node) throws TbNodeException { ObjectMapper mapper = JacksonUtil.OBJECT_MAPPER; TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(getTbNodeConfig())); @@ -117,7 +117,6 @@ public abstract class AbstractAttributeNodeTest { } void errorThrownIfCannotLoadAttributesAsync(User user) { - msg = TbMsg.newMsg("USER", user.getId(), new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); when(ctx.getAttributesService()).thenReturn(attributesService); @@ -168,7 +167,7 @@ public abstract class AbstractAttributeNodeTest { ObjectMapper mapper = JacksonUtil.OBJECT_MAPPER; TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(getTbNodeConfigForTelemetry())); - TbEntityGetAttrNode node = getEmptyNode(); + TbAbstractGetEntityAttrNode node = getEmptyNode(); node.init(null, nodeConfiguration); msg = TbMsg.newMsg("DEVICE", device.getId(), new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); @@ -210,10 +209,11 @@ public abstract class AbstractAttributeNodeTest { conf.put(keyAttrConf, valueAttrConf); config.setAttrMapping(conf); config.setTelemetry(isTelemetry); + config.setFetchTo(FetchTo.METADATA); return config; } - protected abstract TbEntityGetAttrNode getEmptyNode(); + protected abstract TbAbstractGetEntityAttrNode getEmptyNode(); abstract EntityId getEntityId(); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNodeTest.java index cfcf1c64a1..853818f226 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNodeTest.java @@ -130,7 +130,7 @@ public class TbAbstractGetAttributesNodeTest { @Test public void fetchToMetadata_whenOnMsg_then_success() throws Exception { - TbGetAttributesNode node = initNode(false, false, false); + TbGetAttributesNode node = initNode(FetchTo.METADATA, false, false); TbMsg msg = getTbMsg(originator); node.onMsg(ctx, msg); @@ -138,9 +138,9 @@ public class TbAbstractGetAttributesNodeTest { TbMsg resultMsg = checkMsg(true); //check attributes - checkAttributes(resultMsg, false, "cs_", clientAttributes); - checkAttributes(resultMsg, false, "ss_", serverAttributes); - checkAttributes(resultMsg, false, "shared_", sharedAttributes); + checkAttributes(resultMsg, FetchTo.METADATA, "cs_", clientAttributes); + checkAttributes(resultMsg, FetchTo.METADATA, "ss_", serverAttributes); + checkAttributes(resultMsg, FetchTo.METADATA, "shared_", sharedAttributes); //check timeseries checkTs(resultMsg, false, false, tsKeys); @@ -148,7 +148,7 @@ public class TbAbstractGetAttributesNodeTest { @Test public void fetchToMetadata_latestWithTs_whenOnMsg_then_success() throws Exception { - TbGetAttributesNode node = initNode(false, true, false); + TbGetAttributesNode node = initNode(FetchTo.METADATA, true, false); TbMsg msg = getTbMsg(originator); node.onMsg(ctx, msg); @@ -156,9 +156,9 @@ public class TbAbstractGetAttributesNodeTest { TbMsg resultMsg = checkMsg(true); //check attributes - checkAttributes(resultMsg, false, "cs_", clientAttributes); - checkAttributes(resultMsg, false, "ss_", serverAttributes); - checkAttributes(resultMsg, false, "shared_", sharedAttributes); + checkAttributes(resultMsg, FetchTo.METADATA, "cs_", clientAttributes); + checkAttributes(resultMsg, FetchTo.METADATA, "ss_", serverAttributes); + checkAttributes(resultMsg, FetchTo.METADATA, "shared_", sharedAttributes); //check timeseries with ts checkTs(resultMsg, false, true, tsKeys); @@ -166,7 +166,7 @@ public class TbAbstractGetAttributesNodeTest { @Test public void fetchToData_whenOnMsg_then_success() throws Exception { - TbGetAttributesNode node = initNode(true, false, false); + TbGetAttributesNode node = initNode(FetchTo.DATA, false, false); TbMsg msg = getTbMsg(originator); node.onMsg(ctx, msg); @@ -174,9 +174,9 @@ public class TbAbstractGetAttributesNodeTest { TbMsg resultMsg = checkMsg(true); //check attributes - checkAttributes(resultMsg, true, "cs_", clientAttributes); - checkAttributes(resultMsg, true, "ss_", serverAttributes); - checkAttributes(resultMsg, true, "shared_", sharedAttributes); + checkAttributes(resultMsg, FetchTo.DATA, "cs_", clientAttributes); + checkAttributes(resultMsg, FetchTo.DATA, "ss_", serverAttributes); + checkAttributes(resultMsg, FetchTo.DATA, "shared_", sharedAttributes); //check timeseries checkTs(resultMsg, true, false, tsKeys); @@ -184,7 +184,7 @@ public class TbAbstractGetAttributesNodeTest { @Test public void fetchToData_latestWithTs_whenOnMsg_then_success() throws Exception { - TbGetAttributesNode node = initNode(true, true, false); + TbGetAttributesNode node = initNode(FetchTo.DATA, true, false); TbMsg msg = getTbMsg(originator); node.onMsg(ctx, msg); @@ -192,9 +192,9 @@ public class TbAbstractGetAttributesNodeTest { TbMsg resultMsg = checkMsg(true); //check attributes - checkAttributes(resultMsg, true, "cs_", clientAttributes); - checkAttributes(resultMsg, true, "ss_", serverAttributes); - checkAttributes(resultMsg, true, "shared_", sharedAttributes); + checkAttributes(resultMsg, FetchTo.DATA, "cs_", clientAttributes); + checkAttributes(resultMsg, FetchTo.DATA, "ss_", serverAttributes); + checkAttributes(resultMsg, FetchTo.DATA, "shared_", sharedAttributes); //check timeseries with ts checkTs(resultMsg, true, true, tsKeys); @@ -202,7 +202,7 @@ public class TbAbstractGetAttributesNodeTest { @Test public void fetchToMetadata_whenOnMsg_then_failure() throws Exception { - TbGetAttributesNode node = initNode(false, false, true); + TbGetAttributesNode node = initNode(FetchTo.METADATA, false, true); TbMsg msg = getTbMsg(originator); node.onMsg(ctx, msg); @@ -210,9 +210,9 @@ public class TbAbstractGetAttributesNodeTest { TbMsg actualMsg = checkMsg(false); //check attributes - checkAttributes(actualMsg, false, "cs_", clientAttributes); - checkAttributes(actualMsg, false, "ss_", serverAttributes); - checkAttributes(actualMsg, false, "shared_", sharedAttributes); + checkAttributes(actualMsg, FetchTo.METADATA, "cs_", clientAttributes); + checkAttributes(actualMsg, FetchTo.METADATA, "ss_", serverAttributes); + checkAttributes(actualMsg, FetchTo.METADATA, "shared_", sharedAttributes); //check timeseries with ts checkTs(actualMsg, false, false, tsKeys); @@ -220,7 +220,7 @@ public class TbAbstractGetAttributesNodeTest { @Test public void fetchToData_whenOnMsg_then_failure() throws Exception { - TbGetAttributesNode node = initNode(true, true, true); + TbGetAttributesNode node = initNode(FetchTo.DATA, true, true); TbMsg msg = getTbMsg(originator); node.onMsg(ctx, msg); @@ -228,9 +228,9 @@ public class TbAbstractGetAttributesNodeTest { TbMsg actualMsg = checkMsg(false); //check attributes - checkAttributes(actualMsg, true, "cs_", clientAttributes); - checkAttributes(actualMsg, true, "ss_", serverAttributes); - checkAttributes(actualMsg, true, "shared_", sharedAttributes); + checkAttributes(actualMsg, FetchTo.DATA, "cs_", clientAttributes); + checkAttributes(actualMsg, FetchTo.DATA, "ss_", serverAttributes); + checkAttributes(actualMsg, FetchTo.DATA, "shared_", sharedAttributes); //check timeseries with ts checkTs(actualMsg, true, true, tsKeys); @@ -238,7 +238,7 @@ public class TbAbstractGetAttributesNodeTest { @Test public void fetchToData_whenOnMsg_and_data_is_not_object_then_failure() throws Exception { - TbGetAttributesNode node = initNode(true, true, true); + TbGetAttributesNode node = initNode(FetchTo.DATA, true, true); TbMsg msg = TbMsg.newMsg("TEST", originator, new TbMsgMetaData(), "[]"); node.onMsg(ctx, msg); @@ -272,13 +272,13 @@ public class TbAbstractGetAttributesNodeTest { return resultMsg; } - private void checkAttributes(TbMsg actualMsg, boolean fetchToData, String prefix, List attributes) { + private void checkAttributes(TbMsg actualMsg, FetchTo fetchTo, String prefix, List attributes) { JsonNode msgData = JacksonUtil.toJsonNode(actualMsg.getData()); attributes.stream() .filter(attribute -> !attribute.equals("unknown")) .forEach(attribute -> { String result; - if (fetchToData) { + if (FetchTo.DATA.equals(fetchTo)) { result = msgData.get(prefix + attribute).asText(); } else { result = actualMsg.getMetaData().getValue(prefix + attribute); @@ -313,13 +313,13 @@ public class TbAbstractGetAttributesNodeTest { } } - private TbGetAttributesNode initNode(boolean fetchToData, boolean getLatestValueWithTs, boolean isTellFailureIfAbsent) throws TbNodeException { + private TbGetAttributesNode initNode(FetchTo fetchTo, boolean getLatestValueWithTs, boolean isTellFailureIfAbsent) throws TbNodeException { TbGetAttributesNodeConfiguration config = new TbGetAttributesNodeConfiguration(); config.setClientAttributeNames(List.of("client_attr_1", "client_attr_2", "${client_attr_metadata}", "unknown")); config.setServerAttributeNames(List.of("server_attr_1", "server_attr_2", "${server_attr_metadata}", "unknown")); config.setSharedAttributeNames(List.of("shared_attr_1", "shared_attr_2", "$[shared_attr_data]", "unknown")); config.setLatestTsKeyNames(List.of("temperature", "humidity", "unknown")); - config.setFetchToData(fetchToData); + config.setFetchTo(fetchTo); config.setGetLatestValueWithTs(getLatestValueWithTs); config.setTellFailureIfAbsent(isTellFailureIfAbsent); TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config)); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java index 1d291545ba..344ce20c20 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java @@ -64,7 +64,7 @@ public class TbFetchDeviceCredentialsNodeTest { callback = mock(TbMsgCallback.class); ctx = mock(TbContext.class); config = new TbFetchDeviceCredentialsNodeConfiguration().defaultConfiguration(); - config.setFetchToMetadata(true); + config.setFetchTo(FetchTo.METADATA); nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config)); node = spy(new TbFetchDeviceCredentialsNode()); node.init(ctx, nodeConfiguration); @@ -89,13 +89,13 @@ public class TbFetchDeviceCredentialsNodeTest { @Test void givenDefaultConfig_whenInit_thenOK() { assertThat(node.config).isEqualTo(config); - assertThat(node.fetchToMetadata).isEqualTo(true); + assertThat(node.fetchTo).isEqualTo(FetchTo.METADATA); } @Test void givenDefaultConfig_whenVerify_thenOK() { TbFetchDeviceCredentialsNodeConfiguration defaultConfig = new TbFetchDeviceCredentialsNodeConfiguration().defaultConfiguration(); - assertThat(defaultConfig.isFetchToMetadata()).isEqualTo(true); + assertThat(defaultConfig.getFetchTo()).isEqualTo(FetchTo.METADATA); } @Test diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java index 10b19add34..f18ac3299b 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,28 +16,47 @@ package org.thingsboard.rule.engine.metadata; import com.datastax.oss.driver.api.core.uuid.Uuids; +import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.junit.MockitoJUnitRunner; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.AssetId; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.UserId; - +import org.thingsboard.server.common.data.kv.AttributeKvEntry; +import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; +import org.thingsboard.server.common.data.kv.StringDataEntry; +import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgDataType; +import org.thingsboard.server.common.msg.TbMsgMetaData; + +import java.util.List; import java.util.UUID; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; @RunWith(MockitoJUnitRunner.class) -public class TbGetCustomerAttributeNodeTest extends AbstractAttributeNodeTest { +public class TbGetCustomerAttributeNodeTest extends TbAbstractAttributeNodeTest { User user = new User(); Asset asset = new Asset(); Device device = new Device(); @@ -56,7 +75,7 @@ public class TbGetCustomerAttributeNodeTest extends AbstractAttributeNodeTest { } @Override - protected TbEntityGetAttrNode getEmptyNode() { + protected TbAbstractGetEntityAttrNode getEmptyNode() { return new TbGetCustomerAttributeNode(); } @@ -65,6 +84,31 @@ public class TbGetCustomerAttributeNodeTest extends AbstractAttributeNodeTest { return customerId; } + @Test + public void errorThrownIfFetchToIsNull() { + var node = new TbGetCustomerAttributeNode(); + var config = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + config.setFetchTo(null); + var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); + + var exception = assertThrows(TbNodeException.class, () -> node.init(ctx, nodeConfiguration)); + + assertThat(exception.getMessage()).isEqualTo("FetchTo cannot be NULL!"); + verify(ctx, never()).tellSuccess(any()); + } + + @Test + public void errorThrownIfMsgDataIsNotAnObjectAndFetchToData() { + node.fetchTo = FetchTo.DATA; + node.config.setFetchTo(FetchTo.DATA); + msg = TbMsg.newMsg("SOME_MESSAGE_TYPE", new CustomerId(UUID.randomUUID()), new TbMsgMetaData(), "[]"); + + var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctx, msg)); + + assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); + verify(ctx, never()).tellSuccess(any()); + } + @Test public void errorThrownIfCannotLoadAttributes() { mockFindUser(user); @@ -89,6 +133,29 @@ public class TbGetCustomerAttributeNodeTest extends AbstractAttributeNodeTest { entityAttributeAddedInMetadata(customerId, "CUSTOMER"); } + @Test + public void customerAttributeAddedInData() { + node.fetchTo = FetchTo.DATA; + node.config.setFetchTo(FetchTo.DATA); + + msg = TbMsg.newMsg("CUSTOMER", customerId, new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); + + List attributes = Lists.newArrayList(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L)); + + when(ctx.getAttributesService()).thenReturn(attributesService); + when(attributesService.find(any(), eq(customerId), eq(SERVER_SCOPE), anyCollection())) + .thenReturn(Futures.immediateFuture(attributes)); + + node.onMsg(ctx, msg); + + var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); + verify(ctx, times(1)).tellSuccess(actualMessageCaptor.capture()); + + var expectedMsgData = "{\"answer\":\"high\"}"; + + assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(expectedMsgData); + } + @Test public void usersCustomerAttributesFetched() { mockFindUser(user); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java new file mode 100644 index 0000000000..77c2cd3130 --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java @@ -0,0 +1,376 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.common.util.ListeningExecutor; +import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNodeConfiguration; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.id.DashboardId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.dao.device.DeviceService; + +import java.util.Collections; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.Callable; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class TbGetOriginatorFieldsNodeTest { + private static final EntityId DUMMY_ENTITY_ID = new DeviceId(UUID.randomUUID()); + public static final ListeningExecutor DB_EXECUTOR = new ListeningExecutor() { + @Override + public ListenableFuture executeAsync(Callable task) { + try { + return Futures.immediateFuture(task.call()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void execute(@NotNull Runnable command) { + command.run(); + } + }; + @Mock + private TbContext ctxMock; + @Mock + private DeviceService deviceService; + private TbGetOriginatorFieldsNode node; + private TbGetOriginatorFieldsConfiguration config; + private TbNodeConfiguration nodeConfiguration; + private TbMsg msg; + + @BeforeEach + public void setUp() { + config = new TbGetOriginatorFieldsConfiguration(); + node = new TbGetOriginatorFieldsNode(); + nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); + } + + @Test + public void givenConfigWithNullFetchTo_whenOnInit_thenException() { + // GIVEN + config = config.defaultConfiguration(); + config.setFetchTo(null); + nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); + + // WHEN + var exception = assertThrows(TbNodeException.class, () -> node.init(ctxMock, nodeConfiguration)); + + // THEN + assertThat(exception.getMessage()).isEqualTo("FetchTo cannot be NULL!"); + verify(ctxMock, never()).tellSuccess(any()); + } + + @Test + public void givenDefaultConfig_whenInit_thenOK() throws TbNodeException { + // GIVEN + config = config.defaultConfiguration(); + nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); + + // WHEN + node.init(ctxMock, nodeConfiguration); + + // THEN + assertThat(node.config).isEqualTo(config); + assertThat(config.getFieldsMapping()).isEqualTo(Map.of( + "name", "originatorName", + "type", "originatorType")); + assertThat(config.isIgnoreNullStrings()).isEqualTo(false); + assertThat(node.fetchTo).isEqualTo(FetchTo.METADATA); + } + + @Test + public void givenCustomConfig_whenInit_thenOK() throws TbNodeException { + // GIVEN + config.setFieldsMapping(Map.of( + "sourceField1", "targetKey1", + "sourceField2", "targetKey2", + "sourceField3", "targetKey3")); + config.setIgnoreNullStrings(true); + config.setFetchTo(FetchTo.DATA); + nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); + + // WHEN + node.init(ctxMock, nodeConfiguration); + + // THEN + assertThat(node.config).isEqualTo(config); + assertThat(config.getFieldsMapping()).isEqualTo(Map.of( + "sourceField1", "targetKey1", + "sourceField2", "targetKey2", + "sourceField3", "targetKey3")); + assertThat(config.isIgnoreNullStrings()).isEqualTo(true); + assertThat(node.fetchTo).isEqualTo(FetchTo.DATA); + } + + @Test + public void givenMsgDataIsNotAnJsonObjectAndFetchToData_whenOnMsg_thenException() { + // GIVEN + node.fetchTo = FetchTo.DATA; + msg = TbMsg.newMsg("SOME_MESSAGE_TYPE", DUMMY_ENTITY_ID, new TbMsgMetaData(), "[]"); + + // WHEN + var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctxMock, msg)); + + // THEN + assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); + verify(ctxMock, never()).tellSuccess(any()); + } + + @Test + public void givenEntityThatDoesNotBelongToTheCurrentTenant_whenOnMsg_thenException() { + // SETUP + var expectedExceptionMessage = "Entity with id: '" + DUMMY_ENTITY_ID + + "' specified in the configuration doesn't belong to the current tenant."; + + // GIVEN + doThrow(new RuntimeException(expectedExceptionMessage)).when(ctxMock).checkTenantEntity(DUMMY_ENTITY_ID); + msg = TbMsg.newMsg("SOME_MESSAGE_TYPE", DUMMY_ENTITY_ID, new TbMsgMetaData(), "{}"); + + // WHEN + var exception = assertThrows(RuntimeException.class, () -> node.onMsg(ctxMock, msg)); + + // THEN + assertThat(exception.getMessage()).isEqualTo(expectedExceptionMessage); + verify(ctxMock, never()).tellSuccess(any()); + } + + @Test + public void givenValidMsgAndFetchToData_whenOnMsg_thenShouldTellSuccessAndFetchToData() { + // GIVEN + var device = new Device(); + device.setId((DeviceId) DUMMY_ENTITY_ID); + device.setName("Test device"); + device.setType("Test device type"); + + config.setFieldsMapping(Map.of( + "name", "originatorName", + "type", "originatorType", + "label", "originatorLabel")); + config.setIgnoreNullStrings(true); + config.setFetchTo(FetchTo.DATA); + + node.config = config; + node.fetchTo = FetchTo.DATA; + var msgMetaData = new TbMsgMetaData(); + var msgData = "{\"temp\":42,\"humidity\":77}"; + msg = TbMsg.newMsg("POST_TELEMETRY_REQUEST", DUMMY_ENTITY_ID, msgMetaData, msgData); + + when(ctxMock.getDeviceService()).thenReturn(deviceService); + when(deviceService.findDeviceByIdAsync(any(), eq(device.getId()))).thenReturn(Futures.immediateFuture(device)); + + when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); + + // WHEN + node.onMsg(ctxMock, msg); + + // THEN + var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); + verify(ctxMock, times(1)).tellSuccess(actualMessageCaptor.capture()); + verify(ctxMock, never()).tellFailure(any(), any()); + + var expectedMsgData = "{\"temp\":42,\"humidity\":77,\"originatorName\":\"Test device\",\"originatorType\":\"Test device type\"}"; + + assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(expectedMsgData); + assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(msgMetaData); + } + + @Test + public void givenValidMsgAndFetchToMetaData_whenOnMsg_thenShouldTellSuccessAndFetchToMetaData() { + // GIVEN + var device = new Device(); + device.setId((DeviceId) DUMMY_ENTITY_ID); + device.setName("Test device"); + device.setType("Test device type"); + + config.setFieldsMapping(Map.of( + "name", "originatorName", + "type", "originatorType", + "label", "originatorLabel")); + config.setIgnoreNullStrings(true); + config.setFetchTo(FetchTo.METADATA); + + node.config = config; + node.fetchTo = FetchTo.METADATA; + var msgMetaData = new TbMsgMetaData(Map.of( + "testKey1", "testValue1", + "testKey2", "123")); + var msgData = "[\"value1\",\"value2\"]"; + msg = TbMsg.newMsg("POST_TELEMETRY_REQUEST", DUMMY_ENTITY_ID, msgMetaData, msgData); + + when(ctxMock.getDeviceService()).thenReturn(deviceService); + when(deviceService.findDeviceByIdAsync(any(), eq(device.getId()))).thenReturn(Futures.immediateFuture(device)); + + when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); + + // WHEN + node.onMsg(ctxMock, msg); + + // THEN + var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); + verify(ctxMock, times(1)).tellSuccess(actualMessageCaptor.capture()); + verify(ctxMock, never()).tellFailure(any(), any()); + + var expectedMsgMetaData = new TbMsgMetaData(Map.of( + "testKey1", "testValue1", + "testKey2", "123", + "originatorName", "Test device", + "originatorType", "Test device type" + )); + + assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(msgData); + assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetaData); + } + + @Test + public void givenNullEntityFieldsAndIgnoreNullStringsFalse_whenOnMsg_thenShouldTellSuccessAndFetchNullField() { + // GIVEN + var device = new Device(); + device.setId((DeviceId) DUMMY_ENTITY_ID); + device.setName("Test device"); + device.setType("Test device type"); + + config.setFieldsMapping(Map.of( + "name", "originatorName", + "type", "originatorType", + "label", "originatorLabel")); + config.setIgnoreNullStrings(false); + config.setFetchTo(FetchTo.METADATA); + + node.config = config; + node.fetchTo = FetchTo.METADATA; + var msgMetaData = new TbMsgMetaData(Map.of( + "testKey1", "testValue1", + "testKey2", "123")); + var msgData = "[\"value1\",\"value2\"]"; + msg = TbMsg.newMsg("POST_TELEMETRY_REQUEST", DUMMY_ENTITY_ID, msgMetaData, msgData); + + when(ctxMock.getDeviceService()).thenReturn(deviceService); + when(deviceService.findDeviceByIdAsync(any(), eq(device.getId()))).thenReturn(Futures.immediateFuture(device)); + + when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); + + // WHEN + node.onMsg(ctxMock, msg); + + // THEN + var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); + verify(ctxMock, times(1)).tellSuccess(actualMessageCaptor.capture()); + verify(ctxMock, never()).tellFailure(any(), any()); + + var expectedMsgMetaData = new TbMsgMetaData(Map.of( + "testKey1", "testValue1", + "testKey2", "123", + "originatorName", "Test device", + "originatorType", "Test device type", + "originatorLabel", "null" + )); + + assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(msgData); + assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetaData); + } + + @Test + public void givenEmptyFieldsMapping_whenOnMsg_thenShouldTellSuccessWithSameMsg() { + // GIVEN + config.setFieldsMapping(Collections.emptyMap()); + config.setIgnoreNullStrings(false); + config.setFetchTo(FetchTo.METADATA); + + node.config = config; + node.fetchTo = FetchTo.METADATA; + var msgMetaData = new TbMsgMetaData(Map.of( + "testKey1", "testValue1", + "testKey2", "123")); + var msgData = "[\"value1\",\"value2\"]"; + msg = TbMsg.newMsg("POST_TELEMETRY_REQUEST", DUMMY_ENTITY_ID, msgMetaData, msgData); + + // WHEN + node.onMsg(ctxMock, msg); + + // THEN + var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); + verify(ctxMock, times(1)).tellSuccess(actualMessageCaptor.capture()); + verify(ctxMock, never()).tellFailure(any(), any()); + + var expectedMsgMetaData = new TbMsgMetaData(Map.of( + "testKey1", "testValue1", + "testKey2", "123" + )); + + assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(msgData); + assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetaData); + } + + @Test + public void givenUnsupportedEntityType_whenOnMsg_thenShouldTellFailureWithSameMsg() { + // GIVEN + config.setFieldsMapping(Map.of( + "name", "originatorName", + "type", "originatorType", + "label", "originatorLabel")); + config.setIgnoreNullStrings(false); + config.setFetchTo(FetchTo.METADATA); + + node.config = config; + node.fetchTo = FetchTo.METADATA; + var msgMetaData = new TbMsgMetaData(Map.of( + "testKey1", "testValue1", + "testKey2", "123")); + var msgData = "[\"value1\",\"value2\"]"; + msg = TbMsg.newMsg("POST_TELEMETRY_REQUEST", new DashboardId(UUID.randomUUID()), msgMetaData, msgData); + + when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); + + // WHEN + node.onMsg(ctxMock, msg); + + // THEN + var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); + verify(ctxMock, times(1)).tellFailure(actualMessageCaptor.capture(), any()); + verify(ctxMock, never()).tellSuccess(any()); + + assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(msgData); + assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(msgMetaData); + } +} \ No newline at end of file diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index 8a41805d26..ef0e94d545 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,12 +15,16 @@ */ package org.thingsboard.rule.engine.metadata; +import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.User; @@ -29,7 +33,13 @@ import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.kv.AttributeKvEntry; +import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; +import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgDataType; +import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.relation.RelationService; import java.util.HashMap; @@ -37,11 +47,19 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; @RunWith(MockitoJUnitRunner.class) -public class TbGetRelatedAttributeNodeTest extends AbstractAttributeNodeTest { +public class TbGetRelatedAttributeNodeTest extends TbAbstractAttributeNodeTest { User user = new User(); Asset asset = new Asset(); Device device = new Device(); @@ -69,7 +87,7 @@ public class TbGetRelatedAttributeNodeTest extends AbstractAttributeNodeTest { } @Override - protected TbEntityGetAttrNode getEmptyNode() { + protected TbAbstractGetEntityAttrNode getEmptyNode() { return new TbGetRelatedAttributeNode(); } @@ -90,6 +108,7 @@ public class TbGetRelatedAttributeNodeTest extends AbstractAttributeNodeTest { conf.put(keyAttrConf, valueAttrConf); config.setAttrMapping(conf); config.setTelemetry(isTelemetry); + config.setFetchTo(FetchTo.METADATA); return config; } @@ -98,6 +117,31 @@ public class TbGetRelatedAttributeNodeTest extends AbstractAttributeNodeTest { return customerId; } + @Test + public void errorThrownIfFetchToIsNull() { + var node = new TbGetRelatedAttributeNode(); + var config = new TbGetRelatedAttrNodeConfiguration().defaultConfiguration(); + config.setFetchTo(null); + var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); + + var exception = assertThrows(TbNodeException.class, () -> node.init(ctx, nodeConfiguration)); + + assertThat(exception.getMessage()).isEqualTo("FetchTo cannot be NULL!"); + verify(ctx, never()).tellSuccess(any()); + } + + @Test + public void errorThrownIfMsgDataIsNotAnObjectAndFetchToData() { + node.fetchTo = FetchTo.DATA; + node.config.setFetchTo(FetchTo.DATA); + msg = TbMsg.newMsg("SOME_MESSAGE_TYPE", new DeviceId(UUID.randomUUID()), new TbMsgMetaData(), "[]"); + + var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctx, msg)); + + assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); + verify(ctx, never()).tellSuccess(any()); + } + @Test public void errorThrownIfCannotLoadAttributes() { entityRelation.setFrom(user.getId()); @@ -130,6 +174,33 @@ public class TbGetRelatedAttributeNodeTest extends AbstractAttributeNodeTest { entityAttributeAddedInMetadata(customerId, "CUSTOMER"); } + @Test + public void customerAttributeAddedInData() { + node.fetchTo = FetchTo.DATA; + node.config.setFetchTo(FetchTo.DATA); + + entityRelation.setFrom(customerId); + entityRelation.setTo(customerId); + when(relationService.findByQuery(any(), any())).thenReturn(Futures.immediateFuture(List.of(entityRelation))); + + msg = TbMsg.newMsg("CUSTOMER", customerId, new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); + + List attributes = Lists.newArrayList(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L)); + + when(ctx.getAttributesService()).thenReturn(attributesService); + when(attributesService.find(any(), eq(customerId), eq(SERVER_SCOPE), anyCollection())) + .thenReturn(Futures.immediateFuture(attributes)); + + node.onMsg(ctx, msg); + + var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); + verify(ctx, times(1)).tellSuccess(actualMessageCaptor.capture()); + + var expectedMsgData = "{\"answer\":\"high\"}"; + + assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(expectedMsgData); + } + @Test public void usersCustomerAttributesFetched() { entityRelation.setFrom(user.getId()); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index 510e97dd9c..ce4dde791a 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,10 +15,15 @@ */ package org.thingsboard.rule.engine.metadata; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.Futures; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.junit.MockitoJUnitRunner; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.User; @@ -26,15 +31,31 @@ import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; - +import org.thingsboard.server.common.data.kv.AttributeKvEntry; +import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; +import org.thingsboard.server.common.data.kv.StringDataEntry; +import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgDataType; +import org.thingsboard.server.common.msg.TbMsgMetaData; + +import java.util.List; import java.util.UUID; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; @RunWith(MockitoJUnitRunner.class) -public class TbGetTenantAttributeNodeTest extends AbstractAttributeNodeTest { - +public class TbGetTenantAttributeNodeTest extends TbAbstractAttributeNodeTest { User user = new User(); Asset asset = new Asset(); Device device = new Device(); @@ -56,7 +77,7 @@ public class TbGetTenantAttributeNodeTest extends AbstractAttributeNodeTest { } @Override - protected TbEntityGetAttrNode getEmptyNode() { + protected TbAbstractGetEntityAttrNode getEmptyNode() { return new TbGetTenantAttributeNode(); } @@ -65,6 +86,31 @@ public class TbGetTenantAttributeNodeTest extends AbstractAttributeNodeTest { return tenantId; } + @Test + public void errorThrownIfFetchToIsNull() { + var node = new TbGetTenantAttributeNode(); + var config = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + config.setFetchTo(null); + var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); + + var exception = assertThrows(TbNodeException.class, () -> node.init(ctx, nodeConfiguration)); + + assertThat(exception.getMessage()).isEqualTo("FetchTo cannot be NULL!"); + verify(ctx, never()).tellSuccess(any()); + } + + @Test + public void errorThrownIfMsgDataIsNotAnObjectAndFetchToData() { + node.fetchTo = FetchTo.DATA; + node.config.setFetchTo(FetchTo.DATA); + msg = TbMsg.newMsg("SOME_MESSAGE_TYPE", new TenantId(UUID.randomUUID()), new TbMsgMetaData(), "[]"); + + var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctx, msg)); + + assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); + verify(ctx, never()).tellSuccess(any()); + } + @Test public void errorThrownIfCannotLoadAttributes() { errorThrownIfCannotLoadAttributes(user); @@ -86,6 +132,29 @@ public class TbGetTenantAttributeNodeTest extends AbstractAttributeNodeTest { entityAttributeAddedInMetadata(tenantId, "TENANT"); } + @Test + public void customerAttributeAddedInData() { + node.fetchTo = FetchTo.DATA; + node.config.setFetchTo(FetchTo.DATA); + + msg = TbMsg.newMsg("TENANT", tenantId, new TbMsgMetaData(metaData), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); + + List attributes = Lists.newArrayList(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L)); + + when(ctx.getAttributesService()).thenReturn(attributesService); + when(attributesService.find(any(), eq(tenantId), eq(SERVER_SCOPE), anyCollection())) + .thenReturn(Futures.immediateFuture(attributes)); + + node.onMsg(ctx, msg); + + var actualMessageCaptor = ArgumentCaptor.forClass(TbMsg.class); + verify(ctx, times(1)).tellSuccess(actualMessageCaptor.capture()); + + var expectedMsgData = "{\"answer\":\"high\"}"; + + assertThat(actualMessageCaptor.getValue().getData()).isEqualTo(expectedMsgData); + } + @Test public void usersCustomerAttributesFetched() { usersCustomerAttributesFetched(user); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java new file mode 100644 index 0000000000..3374e8e011 --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java @@ -0,0 +1,231 @@ +package org.thingsboard.rule.engine.util; + +import com.google.common.util.concurrent.Futures; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.thingsboard.rule.engine.api.RuleEngineAlarmService; +import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.BaseData; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EntityFieldsData; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.id.AlarmId; +import org.thingsboard.server.common.data.id.AssetId; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.id.EntityViewId; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UUIDBased; +import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.dao.asset.AssetService; +import org.thingsboard.server.dao.customer.CustomerService; +import org.thingsboard.server.dao.device.DeviceService; +import org.thingsboard.server.dao.entityview.EntityViewService; +import org.thingsboard.server.dao.rule.RuleChainService; +import org.thingsboard.server.dao.tenant.TenantService; +import org.thingsboard.server.dao.user.UserService; + +import java.util.EnumSet; +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class EntitiesFieldsAsyncLoaderTest { + private static EnumSet SUPPORTED_ENTITY_TYPES; + private static UUID RANDOM_UUID; + private static TenantId TENANT_ID; + @Mock + private TbContext ctxMock; + @Mock + private TenantService tenantServiceMock; + @Mock + private CustomerService customerServiceMock; + @Mock + private UserService userServiceMock; + @Mock + private AssetService assetServiceMock; + @Mock + private DeviceService deviceServiceMock; + @Mock + private RuleEngineAlarmService ruleEngineAlarmServiceMock; + @Mock + private RuleChainService ruleChainServiceMock; + @Mock + private EntityViewService entityViewServiceMock; + + @BeforeAll + public static void setup() { + RANDOM_UUID = UUID.randomUUID(); + TENANT_ID = new TenantId(UUID.randomUUID()); + SUPPORTED_ENTITY_TYPES = EnumSet.of( + EntityType.TENANT, + EntityType.CUSTOMER, + EntityType.USER, + EntityType.ASSET, + EntityType.DEVICE, + EntityType.ALARM, + EntityType.RULE_CHAIN, + EntityType.ENTITY_VIEW + ); + } + + @Test + public void givenSupportedEntityTypes_whenFindAsync_thenOK() throws ExecutionException, InterruptedException { + for (var entityType : SUPPORTED_ENTITY_TYPES) { + var entityId = EntityIdFactory.getByTypeAndUuid(entityType, RANDOM_UUID); + + initMocks(entityType, false); + + when(ctxMock.getTenantId()).thenReturn(TENANT_ID); + + var actualEntityFieldsData = EntitiesFieldsAsyncLoader.findAsync(ctxMock, entityId).get(); + var expectedEntityFieldsData = new EntityFieldsData(getEntityFromEntityId(entityId)); + + Assertions.assertEquals(expectedEntityFieldsData, actualEntityFieldsData); + } + } + + @Test + public void givenUnsupportedEntityTypes_whenFindAsync_thenException() { + for (var entityType : EntityType.values()) { + if (!SUPPORTED_ENTITY_TYPES.contains(entityType)) { + var entityId = EntityIdFactory.getByTypeAndUuid(entityType, RANDOM_UUID); + + var expectedExceptionMsg = "org.thingsboard.rule.engine.api.TbNodeException: Unexpected originator EntityType: " + entityType; + + var exception = assertThrows(ExecutionException.class, + () -> EntitiesFieldsAsyncLoader.findAsync(ctxMock, entityId).get()); + + assertInstanceOf(TbNodeException.class, exception.getCause()); + assertThat(exception.getMessage()).isEqualTo(expectedExceptionMsg); + } + } + } + + @Test + public void givenSupportedTypeButEntityDoesNotExist_whenFindAsync_thenException() { + for (var entityType : SUPPORTED_ENTITY_TYPES) { + var entityId = EntityIdFactory.getByTypeAndUuid(entityType, RANDOM_UUID); + + initMocks(entityType, true); + when(ctxMock.getTenantId()).thenReturn(TENANT_ID); + + var expectedExceptionMsg = "org.thingsboard.rule.engine.api.TbNodeException: Entity not found!"; + + var exception = assertThrows(ExecutionException.class, + () -> EntitiesFieldsAsyncLoader.findAsync(ctxMock, entityId).get()); + + assertInstanceOf(TbNodeException.class, exception.getCause()); + assertThat(exception.getMessage()).isEqualTo(expectedExceptionMsg); + } + } + + private void initMocks(EntityType entityType, boolean entityDoesNotExist) { + switch (entityType) { + case TENANT: + var tenant = Futures.immediateFuture(entityDoesNotExist ? null : new Tenant(new TenantId(RANDOM_UUID))); + + when(ctxMock.getTenantService()).thenReturn(tenantServiceMock); + doReturn(tenant).when(tenantServiceMock).findTenantByIdAsync(eq(TENANT_ID), any()); + + break; + case CUSTOMER: + var customer = Futures.immediateFuture(entityDoesNotExist ? null : new Customer(new CustomerId(RANDOM_UUID))); + + when(ctxMock.getCustomerService()).thenReturn(customerServiceMock); + doReturn(customer).when(customerServiceMock).findCustomerByIdAsync(eq(TENANT_ID), any()); + + break; + case USER: + var user = Futures.immediateFuture(entityDoesNotExist ? null : new User(new UserId(RANDOM_UUID))); + + when(ctxMock.getUserService()).thenReturn(userServiceMock); + doReturn(user).when(userServiceMock).findUserByIdAsync(eq(TENANT_ID), any()); + + break; + case ASSET: + var asset = Futures.immediateFuture(entityDoesNotExist ? null : new Asset(new AssetId(RANDOM_UUID))); + + when(ctxMock.getAssetService()).thenReturn(assetServiceMock); + doReturn(asset).when(assetServiceMock).findAssetByIdAsync(eq(TENANT_ID), any()); + + break; + case DEVICE: + var device = Futures.immediateFuture(entityDoesNotExist ? null : new Device(new DeviceId(RANDOM_UUID))); + + when(ctxMock.getDeviceService()).thenReturn(deviceServiceMock); + doReturn(device).when(deviceServiceMock).findDeviceByIdAsync(eq(TENANT_ID), any()); + + break; + case ALARM: + var alarm = Futures.immediateFuture(entityDoesNotExist ? null : new Alarm(new AlarmId(RANDOM_UUID))); + + when(ctxMock.getAlarmService()).thenReturn(ruleEngineAlarmServiceMock); + doReturn(alarm).when(ruleEngineAlarmServiceMock).findAlarmByIdAsync(eq(TENANT_ID), any()); + + break; + case RULE_CHAIN: + var ruleChain = Futures.immediateFuture(entityDoesNotExist ? null : new RuleChain(new RuleChainId(RANDOM_UUID))); + + when(ctxMock.getRuleChainService()).thenReturn(ruleChainServiceMock); + doReturn(ruleChain).when(ruleChainServiceMock).findRuleChainByIdAsync(eq(TENANT_ID), any()); + + break; + case ENTITY_VIEW: + var entityView = Futures.immediateFuture(entityDoesNotExist ? null : new EntityView(new EntityViewId(RANDOM_UUID))); + + when(ctxMock.getEntityViewService()).thenReturn(entityViewServiceMock); + doReturn(entityView).when(entityViewServiceMock).findEntityViewByIdAsync(eq(TENANT_ID), any()); + + break; + default: + throw new RuntimeException("Unexpected EntityType: " + entityType); + } + } + + private BaseData getEntityFromEntityId(EntityId entityId) { + switch (entityId.getEntityType()) { + case TENANT: + return new Tenant((TenantId) entityId); + case CUSTOMER: + return new Customer((CustomerId) entityId); + case USER: + return new User((UserId) entityId); + case ASSET: + return new Asset((AssetId) entityId); + case DEVICE: + return new Device((DeviceId) entityId); + case ALARM: + return new Alarm((AlarmId) entityId); + case RULE_CHAIN: + return new RuleChain((RuleChainId) entityId); + case ENTITY_VIEW: + return new EntityView((EntityViewId) entityId); + default: + throw new RuntimeException("Unexpected EntityType: " + entityId.getEntityType()); + } + } +} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/TenantIdLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/TenantIdLoaderTest.java index 6f937d7e18..4675784bc8 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/TenantIdLoaderTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/TenantIdLoaderTest.java @@ -56,7 +56,6 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetsBundle; -import org.thingsboard.server.dao.alarm.AlarmCommentService; import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.dashboard.DashboardService; @@ -94,8 +93,6 @@ public class TenantIdLoaderTest { @Mock private RuleEngineAlarmService alarmService; @Mock - private AlarmCommentService alarmCommentService; - @Mock private RuleChainService ruleChainService; @Mock private EntityViewService entityViewService; @@ -312,9 +309,8 @@ public class TenantIdLoaderTest { break; default: - throw new RuntimeException("Unexpected original EntityType " + entityType); + throw new RuntimeException("Unexpected originator EntityType " + entityType); } - } private EntityId getEntityId(EntityType entityType) { @@ -350,5 +346,4 @@ public class TenantIdLoaderTest { public void test_findEntityIdAsync_other_tenant() { checkTenant(new TenantId(UUID.randomUUID()), false); } - } From 89a504da6694537c3da9a66feb93292c2ab99d67 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 23 Mar 2023 12:58:14 +0200 Subject: [PATCH 009/207] Format license headers --- .../engine/util/EntitiesFieldsAsyncLoader.java | 8 ++++---- .../metadata/TbAbstractAttributeNodeTest.java | 8 ++++---- .../metadata/TbGetCustomerAttributeNodeTest.java | 8 ++++---- .../metadata/TbGetOriginatorFieldsNodeTest.java | 8 ++++---- .../metadata/TbGetRelatedAttributeNodeTest.java | 8 ++++---- .../metadata/TbGetTenantAttributeNodeTest.java | 8 ++++---- .../util/EntitiesFieldsAsyncLoaderTest.java | 15 +++++++++++++++ 7 files changed, 39 insertions(+), 24 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java index 9d78005e23..0d54e5ddc1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java index a3949587b9..8ff873ceb4 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java index f18ac3299b..16c3219c6e 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java index 77c2cd3130..a258cf4c94 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index ef0e94d545..0ed1296d18 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index ce4dde791a..6537657a7f 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java index 3374e8e011..5dfd8be03f 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoaderTest.java @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.rule.engine.util; import com.google.common.util.concurrent.Futures; From 63e01ec38e2f03c9f023450997549e36616a70e5 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 23 Mar 2023 17:16:45 +0200 Subject: [PATCH 010/207] Add update script --- .../install/ThingsboardInstallService.java | 1 + .../update/DefaultDataUpdateService.java | 98 +++++++++++++++++++ .../metadata/TbGetTenantDetailsNode.java | 2 +- 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index c0f4bd5cf4..a1a55f5e14 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -242,6 +242,7 @@ public class ThingsboardInstallService { databaseEntitiesUpgradeService.upgradeDatabase("3.4.4"); log.info("Updating system data..."); systemDataLoaderService.updateSystemWidgets(); + dataUpdateService.updateData("3.4.4"); break; //TODO update CacheCleanupService on the next version upgrade default: diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 43d6a4df0a..08fa99233a 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -28,6 +28,16 @@ import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.flow.TbRuleChainInputNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; +import org.thingsboard.rule.engine.metadata.FetchTo; +import org.thingsboard.rule.engine.metadata.TbFetchDeviceCredentialsNode; +import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; +import org.thingsboard.rule.engine.metadata.TbGetCustomerAttributeNode; +import org.thingsboard.rule.engine.metadata.TbGetCustomerDetailsNode; +import org.thingsboard.rule.engine.metadata.TbGetDeviceAttrNode; +import org.thingsboard.rule.engine.metadata.TbGetOriginatorFieldsNode; +import org.thingsboard.rule.engine.metadata.TbGetRelatedAttributeNode; +import org.thingsboard.rule.engine.metadata.TbGetTenantAttributeNode; +import org.thingsboard.rule.engine.metadata.TbGetTenantDetailsNode; import org.thingsboard.rule.engine.profile.TbDeviceProfileNode; import org.thingsboard.rule.engine.profile.TbDeviceProfileNodeConfiguration; import org.thingsboard.server.common.data.DataConstants; @@ -46,6 +56,7 @@ import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.query.DynamicValue; @@ -83,6 +94,7 @@ import org.thingsboard.server.service.install.TbRuleEngineQueueConfigService; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; @@ -203,11 +215,97 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Skipping edge events migration"); } break; + case "3.4.4": + log.info("Updating data from version 3.4.4 to 3.5.0 ..."); + log.info("Started enrichment rule nodes update ..."); + updateEnrichmentRuleNodes(); + log.info("Finished enrichment rule nodes update ..."); + break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } } + private void updateEnrichmentRuleNodes() { + try { + var ruleNodeTypesToUpdate = List.of( + TbGetOriginatorFieldsNode.class.getName(), + TbFetchDeviceCredentialsNode.class.getName(), + TbGetAttributesNode.class.getName(), + TbGetDeviceAttrNode.class.getName(), + TbGetRelatedAttributeNode.class.getName(), + TbGetTenantAttributeNode.class.getName(), + TbGetCustomerAttributeNode.class.getName(), + TbGetCustomerDetailsNode.class.getName(), + TbGetTenantDetailsNode.class.getName() + ); + var ruleChainIdToTenantId = new HashMap(); + ruleNodeTypesToUpdate.forEach(ruleNodeType -> { + var ruleNodes = new PageDataIterable<>( + pageLink -> ruleChainService.findAllRuleNodesByType(ruleNodeType, pageLink), 1024 + ); + for (var ruleNode : ruleNodes) { + var configuration = ruleNode.getConfiguration(); + if (configuration == null) { + log.error("Unable to update [{}] rule node with ID [{}]! Node configuration is null! Skipping this node!", + ruleNodeType, ruleNode.getId()); + continue; + } + if (!configuration.isObject()) { + log.error("Unable to update [{}] rule node with ID [{}]! Node configuration is not an object! Skipping this node!", + ruleNodeType, ruleNode.getId()); + continue; + } + var configObjectNode = (ObjectNode) configuration; + var fetchTo = FetchTo.METADATA; + if (configObjectNode.has("fetchToMetadata")) { + var fetchToMetadata = configObjectNode.get("fetchToMetadata").asText(); + if ("true".equals(fetchToMetadata)) { + fetchTo = FetchTo.METADATA; + } else if ("false".equals(fetchToMetadata)) { + fetchTo = FetchTo.DATA; + } else { + log.error("[fetchToMetadata] property has unexpected value: {}! Expected true or false! Skipping this node ID[{}]!", + fetchToMetadata, ruleNode.getId()); + } + configObjectNode.remove("fetchToMetadata"); + } + if (configObjectNode.has("fetchToData")) { + var fetchToData = configObjectNode.get("fetchToData").asText(); + if ("true".equals(fetchToData)) { + fetchTo = FetchTo.DATA; + } else if ("false".equals(fetchToData)) { + fetchTo = FetchTo.METADATA; + } else { + log.error("[fetchToData] property has unexpected value: {}! Expected true or false! Skipping this node ID[{}]!", + fetchToData, ruleNode.getId()); + } + configObjectNode.remove("fetchToData"); + } + if (configObjectNode.has("addToMetadata")) { + var addToMetadata = configObjectNode.get("addToMetadata").asText(); + if ("true".equals(addToMetadata)) { + fetchTo = FetchTo.METADATA; + } else if ("false".equals(addToMetadata)) { + fetchTo = FetchTo.DATA; + } else { + log.error("[addToMetadata] property has unexpected value: {}! Skipping Expected true or false! Skipping this node ID[{}]!", + addToMetadata, ruleNode.getId()); + } + configObjectNode.remove("addToMetadata"); + } + configObjectNode.put("fetchTo", fetchTo.toString()); + ruleNode.setConfiguration(configObjectNode); + ruleChainIdToTenantId.computeIfAbsent(ruleNode.getRuleChainId(), + ruleChainId -> ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, ruleNode.getRuleChainId()).getTenantId()); + ruleChainService.saveRuleNode(ruleChainIdToTenantId.get(ruleNode.getRuleChainId()), ruleNode); + } + }); + } catch (Exception e) { + log.error("Unexpected error during enrichment rule nodes updating!", e); + } + } + private final PaginatedUpdater deviceProfileEntityDynamicConditionsUpdater = new PaginatedUpdater<>() { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index 983b17e61e..4091226020 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -38,7 +38,7 @@ import org.thingsboard.server.common.msg.TbMsg; "Note: only Device, Asset, and Entity View type are allowed.

" + "If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to Failure chain, otherwise, Success chain will be used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, - configDirective = "tbEnrichmentNodeEntityDetailsConfig") + configDirective = "") // tbEnrichmentNodeEntityDetailsConfig public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode { private static final String TENANT_PREFIX = "tenant_"; From 85e40e78c4bb541e55b2aa3ad85243a95aef0053 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 23 Mar 2023 17:21:57 +0200 Subject: [PATCH 011/207] Fix "Unknown" error cause in enrichment rule nodes --- .../rule/engine/metadata/TbAbstractGetAttributesNode.java | 4 ++-- .../rule/engine/metadata/TbAbstractGetEntityAttrNode.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java index 378e7d1358..866fbfd190 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java @@ -40,12 +40,12 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import static org.thingsboard.common.util.DonAsynchron.withCallback; -import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE; import static org.thingsboard.server.common.data.DataConstants.CLIENT_SCOPE; import static org.thingsboard.server.common.data.DataConstants.LATEST_TS; import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; @@ -80,7 +80,7 @@ public abstract class TbAbstractGetAttributesNode extends Tb private void safeGetAttributes(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) { if (entityId == null || entityId.isNullUid()) { - ctx.tellNext(msg, FAILURE); + ctx.tellFailure(msg, new NoSuchElementException("Did not find entity! Msg ID: " + msg.getId())); return; } From f5285ab4855aebef9f043a710b6ed61163a2f01c Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 24 Mar 2023 12:22:03 +0200 Subject: [PATCH 012/207] Minor fixes and improvements --- .../TbAbstractFetchToNodeConfiguration.java | 8 ++--- .../metadata/TbAbstractGetAttributesNode.java | 35 +++++++++---------- .../metadata/TbAbstractGetEntityAttrNode.java | 8 ++--- .../TbAbstractGetEntityDetailsNode.java | 19 ++++++---- ...ractGetEntityDetailsNodeConfiguration.java | 8 ++--- .../TbFetchDeviceCredentialsNode.java | 12 +++---- ...tchDeviceCredentialsNodeConfiguration.java | 10 +++--- .../engine/metadata/TbGetAttributesNode.java | 8 ++--- .../TbGetAttributesNodeConfiguration.java | 11 +++--- .../metadata/TbGetCustomerAttributeNode.java | 8 ++--- .../metadata/TbGetCustomerDetailsNode.java | 11 +++--- ...TbGetCustomerDetailsNodeConfiguration.java | 10 +++--- .../engine/metadata/TbGetDeviceAttrNode.java | 8 ++--- .../TbGetDeviceAttrNodeConfiguration.java | 12 +++---- .../TbGetEntityAttrNodeConfiguration.java | 14 ++++---- .../TbGetOriginatorFieldsConfiguration.java | 12 +++---- .../metadata/TbGetOriginatorFieldsNode.java | 8 ++--- .../TbGetRelatedAttrNodeConfiguration.java | 19 +++++----- .../metadata/TbGetRelatedAttributeNode.java | 8 ++--- .../metadata/TbGetTenantAttributeNode.java | 10 +++--- .../metadata/TbGetTenantDetailsNode.java | 12 +++---- .../transform/TbAbstractTransformNode.java | 14 ++++---- .../metadata/TbAbstractAttributeNodeTest.java | 16 +++++---- 23 files changed, 142 insertions(+), 139 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java index 63ddf9be5f..ff335d824b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java index 866fbfd190..0a9c3c8703 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,8 +15,6 @@ */ package org.thingsboard.rule.engine.metadata; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -34,7 +32,6 @@ import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.msg.TbMsg; -import org.thingsboard.server.common.msg.TbMsgMetaData; import java.util.ArrayList; import java.util.HashMap; @@ -89,7 +86,7 @@ public abstract class TbAbstractGetAttributesNode> failuresMap = new ConcurrentHashMap<>(); + var failuresMap = new ConcurrentHashMap>(); ListenableFuture>>> allFutures = Futures.allAsList( getLatestTelemetry(ctx, entityId, TbNodeUtils.processPatterns(config.getLatestTsKeyNames(), msg), failuresMap), getAttrAsync(ctx, entityId, CLIENT_SCOPE, TbNodeUtils.processPatterns(config.getClientAttributeNames(), msg), failuresMap), @@ -97,12 +94,12 @@ public abstract class TbAbstractGetAttributesNode { - TbMsgMetaData msgMetaData = msg.getMetaData().copy(); + var msgMetaData = msg.getMetaData().copy(); futuresList.stream().filter(Objects::nonNull).forEach(kvEntriesMap -> { kvEntriesMap.forEach((keyScope, kvEntryList) -> { - String prefix = getPrefix(keyScope); + var prefix = getPrefix(keyScope); kvEntryList.forEach(kvEntry -> { - String key = prefix + kvEntry.getKey(); + var key = prefix + kvEntry.getKey(); if (FetchTo.DATA.equals(fetchTo)) { JacksonUtil.addKvEntry(msgDataNode, kvEntry, key); } else if (FetchTo.METADATA.equals(fetchTo)) { @@ -131,12 +128,12 @@ public abstract class TbAbstractGetAttributesNode> attributeKvEntryListFuture = ctx.getAttributesService().find(ctx.getTenantId(), entityId, scope, keys); + var attributeKvEntryListFuture = ctx.getAttributesService().find(ctx.getTenantId(), entityId, scope, keys); return Futures.transform(attributeKvEntryListFuture, attributeKvEntryList -> { if (isTellFailureIfAbsent && attributeKvEntryList.size() != keys.size()) { getNotExistingKeys(attributeKvEntryList, keys).forEach(key -> computeFailuresMap(scope, failuresMap, key)); } - Map> mapAttributeKvEntry = new HashMap<>(); + var mapAttributeKvEntry = new HashMap>(); mapAttributeKvEntry.put(scope, attributeKvEntryList); return mapAttributeKvEntry; }, MoreExecutors.directExecutor()); @@ -148,7 +145,7 @@ public abstract class TbAbstractGetAttributesNode> latestTelemetryFutures = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, keys); return Futures.transform(latestTelemetryFutures, tsKvEntries -> { - List listTsKvEntry = new ArrayList<>(); + var listTsKvEntry = new ArrayList(); tsKvEntries.forEach(tsKvEntry -> { if (tsKvEntry.getValue() == null) { if (isTellFailureIfAbsent) { @@ -160,22 +157,22 @@ public abstract class TbAbstractGetAttributesNode> mapTsKvEntry = new HashMap<>(); + var mapTsKvEntry = new HashMap>(); mapTsKvEntry.put(LATEST_TS, listTsKvEntry); return mapTsKvEntry; }, MoreExecutors.directExecutor()); } private TsKvEntry getValueWithTs(TsKvEntry tsKvEntry) { - ObjectMapper mapper = FetchTo.DATA.equals(fetchTo) ? JacksonUtil.OBJECT_MAPPER : JacksonUtil.ALLOW_UNQUOTED_FIELD_NAMES_MAPPER; - ObjectNode value = JacksonUtil.newObjectNode(mapper); + var mapper = FetchTo.DATA.equals(fetchTo) ? JacksonUtil.OBJECT_MAPPER : JacksonUtil.ALLOW_UNQUOTED_FIELD_NAMES_MAPPER; + var value = JacksonUtil.newObjectNode(mapper); value.put(TS, tsKvEntry.getTs()); JacksonUtil.addKvEntry(value, tsKvEntry, VALUE, mapper); return new BasicTsKvEntry(tsKvEntry.getTs(), new JsonDataEntry(tsKvEntry.getKey(), value.toString())); } private String getPrefix(String scope) { - String prefix = ""; + var prefix = ""; switch (scope) { case CLIENT_SCOPE: prefix = "cs_"; @@ -201,7 +198,7 @@ public abstract class TbAbstractGetAttributesNode> failuresMap) { - StringBuilder errorMessage = new StringBuilder("The following attribute/telemetry keys is not present in the DB: ").append("\n"); + var errorMessage = new StringBuilder("The following attribute/telemetry keys is not present in the DB: ").append("\n"); if (failuresMap.containsKey(CLIENT_SCOPE)) { errorMessage.append("\t").append("[" + CLIENT_SCOPE + "]:").append(failuresMap.get(CLIENT_SCOPE).toString()).append("\n"); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java index 874cee2e75..3a02bfa4d5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java index 21918029ef..df46e35226 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -29,7 +29,6 @@ import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.util.EntityDetails; import org.thingsboard.server.common.data.ContactBased; -import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -56,10 +55,16 @@ public abstract class TbAbstractGetEntityDetailsNode getContactBasedListenableFuture(TbContext ctx, TbMsg msg); protected MessageData getDataAsJson(TbMsg msg) { - if (config.getFetchTo() == FetchTo.METADATA) { + if (fetchTo == FetchTo.METADATA) { return new MessageData(gson.toJsonTree(msg.getMetaData().getData(), TYPE), DataSource.METADATA); + } else if (fetchTo == FetchTo.DATA) { + var msgDataJsonElement = JsonParser.parseString(msg.getData()); + if (!msgDataJsonElement.isJsonObject()) { + throw new IllegalArgumentException("Message body is not an object!"); + } + return new MessageData(msgDataJsonElement, DataSource.DATA); } else { - return new MessageData(JsonParser.parseString(msg.getData()), DataSource.DATA); + throw new IllegalArgumentException("Unsupported fetchTo value!"); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java index 1da798ae82..0d2840d35c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java index abded26923..99bba12229 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,7 +15,6 @@ */ package org.thingsboard.rule.engine.metadata; -import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RuleNode; @@ -55,6 +54,7 @@ public class TbFetchDeviceCredentialsNode extends TbAbstractNodeWithFetchTo * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -26,7 +26,7 @@ import org.thingsboard.rule.engine.api.NodeConfiguration; public class TbFetchDeviceCredentialsNodeConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { @Override public TbFetchDeviceCredentialsNodeConfiguration defaultConfiguration() { - TbFetchDeviceCredentialsNodeConfiguration configuration = new TbFetchDeviceCredentialsNodeConfiguration(); + var configuration = new TbFetchDeviceCredentialsNodeConfiguration(); configuration.setFetchTo(FetchTo.METADATA); return configuration; } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index 0cd8b9cade..a280442052 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java index 7c2b515668..4dbb5f98a4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,6 +18,7 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; + import java.util.Collections; import java.util.List; @@ -38,7 +39,7 @@ public class TbGetAttributesNodeConfiguration extends TbAbstractFetchToNodeConfi @Override public TbGetAttributesNodeConfiguration defaultConfiguration() { - TbGetAttributesNodeConfiguration configuration = new TbGetAttributesNodeConfiguration(); + var configuration = new TbGetAttributesNodeConfiguration(); configuration.setClientAttributeNames(Collections.emptyList()); configuration.setSharedAttributeNames(Collections.emptyList()); configuration.setServerAttributeNames(Collections.emptyList()); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index d00de4dd0e..9796289ba5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index cdcf522876..18e5c76c10 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -33,7 +33,6 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; @@ -97,7 +96,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -26,7 +26,7 @@ import java.util.Collections; public class TbGetCustomerDetailsNodeConfiguration extends TbAbstractGetEntityDetailsNodeConfiguration implements NodeConfiguration { @Override public TbGetCustomerDetailsNodeConfiguration defaultConfiguration() { - TbGetCustomerDetailsNodeConfiguration configuration = new TbGetCustomerDetailsNodeConfiguration(); + var configuration = new TbGetCustomerDetailsNodeConfiguration(); configuration.setDetailsList(Collections.emptyList()); configuration.setFetchTo(FetchTo.METADATA); return configuration; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java index 96230ae28f..20eae3ec99 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java index f3ba3651cc..0dffad1884 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,7 +30,7 @@ public class TbGetDeviceAttrNodeConfiguration extends TbGetAttributesNodeConfigu @Override public TbGetDeviceAttrNodeConfiguration defaultConfiguration() { - TbGetDeviceAttrNodeConfiguration configuration = new TbGetDeviceAttrNodeConfiguration(); + var configuration = new TbGetDeviceAttrNodeConfiguration(); configuration.setClientAttributeNames(Collections.emptyList()); configuration.setSharedAttributeNames(Collections.emptyList()); configuration.setServerAttributeNames(Collections.emptyList()); @@ -39,7 +39,7 @@ public class TbGetDeviceAttrNodeConfiguration extends TbGetAttributesNodeConfigu configuration.setGetLatestValueWithTs(false); configuration.setFetchTo(FetchTo.METADATA); - DeviceRelationsQuery deviceRelationsQuery = new DeviceRelationsQuery(); + var deviceRelationsQuery = new DeviceRelationsQuery(); deviceRelationsQuery.setDirection(EntitySearchDirection.FROM); deviceRelationsQuery.setMaxLevel(1); deviceRelationsQuery.setRelationType(EntityRelation.CONTAINS_TYPE); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java index 12a94e227f..c6f6b36f72 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,9 +30,9 @@ public class TbGetEntityAttrNodeConfiguration extends TbAbstractFetchToNodeConfi @Override public TbGetEntityAttrNodeConfiguration defaultConfiguration() { - TbGetEntityAttrNodeConfiguration configuration = new TbGetEntityAttrNodeConfiguration(); - Map attrMapping = new HashMap<>(); - attrMapping.putIfAbsent("temperature", "tempo"); + var configuration = new TbGetEntityAttrNodeConfiguration(); + var attrMapping = new HashMap(); + attrMapping.putIfAbsent("serialNumber", "sn"); configuration.setAttrMapping(attrMapping); configuration.setTelemetry(false); configuration.setFetchTo(FetchTo.METADATA); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java index b2f7ea2b26..5d1dd87237 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,8 +30,8 @@ public class TbGetOriginatorFieldsConfiguration extends TbAbstractFetchToNodeCon @Override public TbGetOriginatorFieldsConfiguration defaultConfiguration() { - TbGetOriginatorFieldsConfiguration configuration = new TbGetOriginatorFieldsConfiguration(); - Map fieldsMapping = new HashMap<>(); + var configuration = new TbGetOriginatorFieldsConfiguration(); + var fieldsMapping = new HashMap(); fieldsMapping.put("name", "originatorName"); fieldsMapping.put("type", "originatorType"); configuration.setFieldsMapping(fieldsMapping); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java index 7dee45aae0..5012ccacc5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java index 8df69c67af..7207fadb80 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,7 +24,6 @@ import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; import java.util.Collections; import java.util.HashMap; -import java.util.Map; @Data @EqualsAndHashCode(callSuper = true) @@ -33,16 +32,16 @@ public class TbGetRelatedAttrNodeConfiguration extends TbGetEntityAttrNodeConfig @Override public TbGetRelatedAttrNodeConfiguration defaultConfiguration() { - TbGetRelatedAttrNodeConfiguration configuration = new TbGetRelatedAttrNodeConfiguration(); - Map attrMapping = new HashMap<>(); - attrMapping.putIfAbsent("temperature", "tempo"); + var configuration = new TbGetRelatedAttrNodeConfiguration(); + var attrMapping = new HashMap(); + attrMapping.putIfAbsent("serialNumber", "sn"); configuration.setAttrMapping(attrMapping); configuration.setTelemetry(false); - RelationsQuery relationsQuery = new RelationsQuery(); + var relationsQuery = new RelationsQuery(); relationsQuery.setDirection(EntitySearchDirection.FROM); relationsQuery.setMaxLevel(1); - RelationEntityTypeFilter relationEntityTypeFilter = new RelationEntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.emptyList()); + var relationEntityTypeFilter = new RelationEntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.emptyList()); relationsQuery.setFilters(Collections.singletonList(relationEntityTypeFilter)); configuration.setRelationsQuery(relationsQuery); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index d722d1c62b..dc9175eab7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index 87b60dfdaf..c31d6b6f12 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType; @Slf4j @RuleNode( type = ComponentType.ENRICHMENT, - name="tenant attributes", + name = "tenant attributes", configClazz = TbGetEntityAttrNodeConfiguration.class, nodeDescription = "Add Originators Tenant Attributes or Latest Telemetry into Message Metadata/Data", nodeDetails = "If Attributes enrichment configured, server scope attributes are added into Message Metadata/Data. " + diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index 4091226020..f8716d4cb2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,7 +25,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.ContactBased; -import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; @@ -38,7 +37,7 @@ import org.thingsboard.server.common.msg.TbMsg; "Note: only Device, Asset, and Entity View type are allowed.

" + "If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to Failure chain, otherwise, Success chain will be used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, - configDirective = "") // tbEnrichmentNodeEntityDetailsConfig + configDirective = "tbEnrichmentNodeEntityDetailsConfig") public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode { private static final String TENANT_PREFIX = "tenant_"; @@ -49,6 +48,7 @@ public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode getDetails(TbContext ctx, TbMsg msg) { + ctx.checkTenantEntity(msg.getOriginator()); return getTbMsgListenableFuture(ctx, msg, getDataAsJson(msg), TENANT_PREFIX); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java index 042c4c0c38..b90a03a432 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,14 +31,12 @@ import org.thingsboard.server.common.msg.queue.TbMsgCallback; import java.util.List; import static org.thingsboard.common.util.DonAsynchron.withCallback; -import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE; /** * Created by ashvayka on 19.01.18. */ @Slf4j public abstract class TbAbstractTransformNode implements TbNode { - private TbTransformNodeConfiguration config; @Override @@ -62,7 +60,7 @@ public abstract class TbAbstractTransformNode implements TbNode { if (m != null) { ctx.tellSuccess(m); } else { - ctx.tellNext(msg, FAILURE); + ctx.tellFailure(msg, new RuntimeException("Message is null!")); } } @@ -85,7 +83,7 @@ public abstract class TbAbstractTransformNode implements TbNode { msgs.forEach(newMsg -> ctx.enqueueForTellNext(newMsg, TbRelationTypes.SUCCESS, wrapper::onSuccess, wrapper::onFailure)); } } else { - ctx.tellNext(msg, FAILURE); + ctx.tellFailure(msg, new RuntimeException("Message or messages list are empty!")); } } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java index 8ff873ceb4..fee6ad38c9 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -52,7 +52,9 @@ import org.thingsboard.server.dao.user.UserService; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -61,7 +63,6 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE; import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; @RunWith(MockitoJUnitRunner.class) @@ -136,7 +137,10 @@ public abstract class TbAbstractAttributeNodeTest { msg = TbMsg.newMsg("USER", user.getId(), new TbMsgMetaData(), TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); node.onMsg(ctx, msg); - verify(ctx).tellNext(msg, FAILURE); + var exceptionCaptor = ArgumentCaptor.forClass(NoSuchElementException.class); + verify(ctx).tellFailure(eq(msg), exceptionCaptor.capture()); + + assertThat(exceptionCaptor.getValue().getMessage()).contains("Did not find entity! Msg ID: "); assertTrue(msg.getMetaData().getData().isEmpty()); } From dc8e9bdeb9c211a775ca7f9760b180de289e27f3 Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Fri, 24 Mar 2023 13:43:51 +0200 Subject: [PATCH 013/207] Fix headers --- .../metadata/TbAbstractFetchToNodeConfiguration.java | 8 ++++---- .../rule/engine/metadata/TbAbstractGetAttributesNode.java | 8 ++++---- .../rule/engine/metadata/TbAbstractGetEntityAttrNode.java | 8 ++++---- .../engine/metadata/TbAbstractGetEntityDetailsNode.java | 8 ++++---- .../TbAbstractGetEntityDetailsNodeConfiguration.java | 8 ++++---- .../engine/metadata/TbFetchDeviceCredentialsNode.java | 8 ++++---- .../TbFetchDeviceCredentialsNodeConfiguration.java | 8 ++++---- .../rule/engine/metadata/TbGetAttributesNode.java | 8 ++++---- .../engine/metadata/TbGetAttributesNodeConfiguration.java | 8 ++++---- .../rule/engine/metadata/TbGetCustomerAttributeNode.java | 8 ++++---- .../rule/engine/metadata/TbGetCustomerDetailsNode.java | 8 ++++---- .../metadata/TbGetCustomerDetailsNodeConfiguration.java | 8 ++++---- .../rule/engine/metadata/TbGetDeviceAttrNode.java | 8 ++++---- .../engine/metadata/TbGetDeviceAttrNodeConfiguration.java | 8 ++++---- .../engine/metadata/TbGetEntityAttrNodeConfiguration.java | 8 ++++---- .../metadata/TbGetOriginatorFieldsConfiguration.java | 8 ++++---- .../rule/engine/metadata/TbGetOriginatorFieldsNode.java | 8 ++++---- .../metadata/TbGetRelatedAttrNodeConfiguration.java | 8 ++++---- .../rule/engine/metadata/TbGetRelatedAttributeNode.java | 8 ++++---- .../rule/engine/metadata/TbGetTenantAttributeNode.java | 8 ++++---- .../rule/engine/metadata/TbGetTenantDetailsNode.java | 8 ++++---- .../rule/engine/transform/TbAbstractTransformNode.java | 8 ++++---- .../rule/engine/metadata/TbAbstractAttributeNodeTest.java | 8 ++++---- 23 files changed, 92 insertions(+), 92 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java index ff335d824b..63ddf9be5f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java index 0a9c3c8703..0c40ace712 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java index 3a02bfa4d5..874cee2e75 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java index df46e35226..4644db2ff7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java index 0d2840d35c..1da798ae82 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java index 99bba12229..0a8ca6b255 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeConfiguration.java index 79ac0eb4cd..62fb3eb797 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index a280442052..0cd8b9cade 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java index 4dbb5f98a4..89c4eb8086 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index 9796289ba5..d00de4dd0e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index 18e5c76c10..300be8cdff 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeConfiguration.java index b54fa02702..06131c4197 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java index 20eae3ec99..96230ae28f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java index 0dffad1884..108a1f5017 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java index c6f6b36f72..fccbdfb39f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java index 5d1dd87237..3c0498f6ba 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java index 5012ccacc5..7dee45aae0 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java index 7207fadb80..9387858811 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index dc9175eab7..d722d1c62b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index c31d6b6f12..dcc96e82c1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index f8716d4cb2..c89259d9ad 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java index b90a03a432..bc693d9b97 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java index fee6ad38c9..7dab0a675d 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbAbstractAttributeNodeTest.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. From f16188ae5883551b2d720698905eb1e144da83d0 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 30 Mar 2023 16:27:17 +0300 Subject: [PATCH 014/207] refactoring rule nodes after review --- .../update/DefaultDataUpdateService.java | 44 ++-- .../rule/engine/api/NodeConfiguration.java | 2 + .../thingsboard/rule/engine/api/TbNode.java | 2 + .../TbAbstractFetchToNodeConfiguration.java | 2 + .../metadata/TbAbstractGetAttributesNode.java | 136 +++++------ .../metadata/TbAbstractGetEntityAttrNode.java | 42 ++-- .../TbAbstractGetEntityDetailsNode.java | 214 ++++++++---------- ...ractGetEntityDetailsNodeConfiguration.java | 2 + .../metadata/TbAbstractNodeWithFetchTo.java | 44 +++- .../TbFetchDeviceCredentialsNode.java | 17 +- .../engine/metadata/TbGetAttributesNode.java | 1 - .../TbGetAttributesNodeConfiguration.java | 2 + .../metadata/TbGetCustomerAttributeNode.java | 23 +- .../metadata/TbGetCustomerDetailsNode.java | 27 ++- ...TbGetCustomerDetailsNodeConfiguration.java | 4 +- .../engine/metadata/TbGetDeviceAttrNode.java | 11 +- .../TbGetDeviceAttrNodeConfiguration.java | 2 + .../TbGetEntityAttrNodeConfiguration.java | 6 +- .../TbGetOriginatorFieldsConfiguration.java | 2 + .../metadata/TbGetOriginatorFieldsNode.java | 61 +++-- .../TbGetRelatedAttrNodeConfiguration.java | 5 +- .../metadata/TbGetRelatedAttributeNode.java | 15 +- .../metadata/TbGetTenantAttributeNode.java | 13 +- .../metadata/TbGetTenantDetailsNode.java | 23 +- .../TbGetTenantDetailsNodeConfiguration.java | 4 +- .../transform/TbAbstractTransformNode.java | 22 +- .../transform/TbChangeOriginatorNode.java | 39 ++-- .../TbChangeOriginatorNodeConfiguration.java | 6 +- .../engine/transform/TbTransformMsgNode.java | 15 +- .../TbTransformMsgNodeConfiguration.java | 2 +- .../TbTransformNodeConfiguration.java | 23 -- .../util/EntitiesCustomerIdAsyncLoader.java | 2 - .../util/EntitiesFieldsAsyncLoader.java | 27 +-- .../transform/TbChangeOriginatorNodeTest.java | 4 +- 34 files changed, 421 insertions(+), 423 deletions(-) delete mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformNodeConfiguration.java diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index a07bddc676..acade3afba 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -217,9 +217,9 @@ public class DefaultDataUpdateService implements DataUpdateService { break; case "3.4.4": log.info("Updating data from version 3.4.4 to 3.5.0 ..."); - log.info("Started enrichment rule nodes update ..."); + log.info("Starting enrichment rule nodes update ..."); updateEnrichmentRuleNodes(); - log.info("Finished enrichment rule nodes update ..."); + log.info("Finished enrichment rule nodes update!"); break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); @@ -247,12 +247,12 @@ public class DefaultDataUpdateService implements DataUpdateService { for (var ruleNode : ruleNodes) { var configuration = ruleNode.getConfiguration(); if (configuration == null) { - log.error("Unable to update [{}] rule node with ID [{}]! Node configuration is null! Skipping this node!", + log.error("Failed to update rule node: [{}] with id: [{}] Node configuration is null! Skipping this node!", ruleNodeType, ruleNode.getId()); continue; } if (!configuration.isObject()) { - log.error("Unable to update [{}] rule node with ID [{}]! Node configuration is not an object! Skipping this node!", + log.error("Failed to update rule node: [{}] with id: [{}] Node configuration is not an object! Skipping this node!", ruleNodeType, ruleNode.getId()); continue; } @@ -265,8 +265,10 @@ public class DefaultDataUpdateService implements DataUpdateService { } else if ("false".equals(fetchToMetadata)) { fetchTo = FetchTo.DATA; } else { - log.error("[fetchToMetadata] property has unexpected value: {}! Expected true or false! Skipping this node ID[{}]!", - fetchToMetadata, ruleNode.getId()); + log.error("Failed to updated rule node: [{}] with id: [{}] " + + "Reason: fetchToMetadata property has unexpected value: {} Allowed values: true or false!", + ruleNodeType, ruleNode.getId(), fetchToMetadata); + continue; } configObjectNode.remove("fetchToMetadata"); } @@ -277,8 +279,10 @@ public class DefaultDataUpdateService implements DataUpdateService { } else if ("false".equals(fetchToData)) { fetchTo = FetchTo.METADATA; } else { - log.error("[fetchToData] property has unexpected value: {}! Expected true or false! Skipping this node ID[{}]!", - fetchToData, ruleNode.getId()); + log.error("Failed to updated rule node: [{}] with id: [{}] " + + "Reason: fetchToData property has unexpected value: {} Allowed values: true or false!", + ruleNodeType, ruleNode.getId(), fetchToData); + continue; } configObjectNode.remove("fetchToData"); } @@ -289,16 +293,28 @@ public class DefaultDataUpdateService implements DataUpdateService { } else if ("false".equals(addToMetadata)) { fetchTo = FetchTo.DATA; } else { - log.error("[addToMetadata] property has unexpected value: {}! Skipping Expected true or false! Skipping this node ID[{}]!", - addToMetadata, ruleNode.getId()); + log.error("Failed to updated rule node: [{}] with id: [{}] " + + "Reason: addToMetadata property has unexpected value: {} Allowed values: true or false!", + ruleNodeType, ruleNode.getId(), addToMetadata); + continue; } configObjectNode.remove("addToMetadata"); } - configObjectNode.put("fetchTo", fetchTo.toString()); + configObjectNode.put("fetchTo", fetchTo.name()); ruleNode.setConfiguration(configObjectNode); - ruleChainIdToTenantId.computeIfAbsent(ruleNode.getRuleChainId(), - ruleChainId -> ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, ruleNode.getRuleChainId()).getTenantId()); - ruleChainService.saveRuleNode(ruleChainIdToTenantId.get(ruleNode.getRuleChainId()), ruleNode); + RuleChainId ruleChainId = ruleNode.getRuleChainId(); + TenantId tenantId = ruleChainIdToTenantId.computeIfAbsent(ruleChainId, + id -> { + RuleChain ruleChain = ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, id); + if (ruleChain == null) { + log.error("Failed to find rule chain by id: [{}], ruleNodeId: [{}]", ruleChainId, ruleNode.getId()); + return null; + } + return ruleChain.getTenantId(); + }); + if (tenantId != null) { + ruleChainService.saveRuleNode(tenantId, ruleNode); + } } }); } catch (Exception e) { diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NodeConfiguration.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NodeConfiguration.java index 8c11ddc110..12a25b517c 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NodeConfiguration.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/NodeConfiguration.java @@ -16,5 +16,7 @@ package org.thingsboard.rule.engine.api; public interface NodeConfiguration { + T defaultConfiguration(); + } diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java index a0fbdaf8e1..b857307247 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbNode.java @@ -24,6 +24,7 @@ import java.util.concurrent.ExecutionException; * Created by ashvayka on 19.01.18. */ public interface TbNode { + void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException; void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException; @@ -33,4 +34,5 @@ public interface TbNode { default void onPartitionChangeMsg(TbContext ctx, PartitionChangeMsg msg) { } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java index 63ddf9be5f..14c27a7ac7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java @@ -19,5 +19,7 @@ import lombok.Data; @Data public abstract class TbAbstractFetchToNodeConfiguration { + private FetchTo fetchTo; + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java index 0c40ace712..5cc2da4d7a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java @@ -19,7 +19,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; @@ -31,14 +33,13 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -48,6 +49,7 @@ import static org.thingsboard.server.common.data.DataConstants.LATEST_TS; import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE; +@Slf4j public abstract class TbAbstractGetAttributesNode extends TbAbstractNodeWithFetchTo { private static final String VALUE = "value"; private static final String TS = "ts"; @@ -58,98 +60,81 @@ public abstract class TbAbstractGetAttributesNode safePutAttributes(ctx, msg, entityId), - t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); - } catch (Throwable th) { - ctx.tellFailure(msg, th); - } + ctx.checkTenantEntity(msg.getOriginator()); + var msgDataAsObjectNode = FetchTo.DATA.equals(fetchTo) ? getMsgDataAsObjectNode(msg) : null; + withCallback( + findEntityIdAsync(ctx, msg), + entityId -> safePutAttributes(ctx, msg, msgDataAsObjectNode, entityId), + t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); } protected abstract ListenableFuture findEntityIdAsync(TbContext ctx, TbMsg msg); - private void safePutAttributes(TbContext ctx, TbMsg msg, T entityId) { - if (entityId == null || entityId.isNullUid()) { - ctx.tellFailure(msg, new NoSuchElementException("Did not find entity! Msg ID: " + msg.getId())); - return; - } - ObjectNode msgDataNode; - if (FetchTo.DATA.equals(fetchTo)) { - msgDataNode = getMsgDataAsObjectNode(msg); - } else { - msgDataNode = null; - } - var failuresMap = new ConcurrentHashMap>(); - ListenableFuture>>> allFutures = Futures.allAsList( - getLatestTelemetry(ctx, entityId, TbNodeUtils.processPatterns(config.getLatestTsKeyNames(), msg), failuresMap), - getAttrAsync(ctx, entityId, CLIENT_SCOPE, TbNodeUtils.processPatterns(config.getClientAttributeNames(), msg), failuresMap), - getAttrAsync(ctx, entityId, SHARED_SCOPE, TbNodeUtils.processPatterns(config.getSharedAttributeNames(), msg), failuresMap), - getAttrAsync(ctx, entityId, SERVER_SCOPE, TbNodeUtils.processPatterns(config.getServerAttributeNames(), msg), failuresMap) + private void safePutAttributes(TbContext ctx, TbMsg msg, ObjectNode msgDataNode, T entityId) { + Set>> failuresPairSet = ConcurrentHashMap.newKeySet(); + var getKvEntryPairFutures = Futures.allAsList( + getLatestTelemetry(ctx, entityId, TbNodeUtils.processPatterns(config.getLatestTsKeyNames(), msg), failuresPairSet), + getAttrAsync(ctx, entityId, CLIENT_SCOPE, TbNodeUtils.processPatterns(config.getClientAttributeNames(), msg), failuresPairSet), + getAttrAsync(ctx, entityId, SHARED_SCOPE, TbNodeUtils.processPatterns(config.getSharedAttributeNames(), msg), failuresPairSet), + getAttrAsync(ctx, entityId, SERVER_SCOPE, TbNodeUtils.processPatterns(config.getServerAttributeNames(), msg), failuresPairSet) ); - withCallback(allFutures, futuresList -> { + withCallback(getKvEntryPairFutures, futuresList -> { var msgMetaData = msg.getMetaData().copy(); - futuresList.stream().filter(Objects::nonNull).forEach(kvEntriesMap -> { - kvEntriesMap.forEach((keyScope, kvEntryList) -> { - var prefix = getPrefix(keyScope); - kvEntryList.forEach(kvEntry -> { - var key = prefix + kvEntry.getKey(); - if (FetchTo.DATA.equals(fetchTo)) { - JacksonUtil.addKvEntry(msgDataNode, kvEntry, key); - } else if (FetchTo.METADATA.equals(fetchTo)) { - msgMetaData.putValue(key, kvEntry.getValueAsString()); - } - }); + futuresList.stream().filter(Objects::nonNull).forEach(kvEntriesPair -> { + var keyScope = kvEntriesPair.getFirst(); + var kvEntryList = kvEntriesPair.getSecond(); + var prefix = getPrefix(keyScope); + kvEntryList.forEach(kvEntry -> { + String targetKey = prefix + kvEntry.getKey(); + enrichMessage(msgDataNode, msgMetaData, kvEntry, targetKey); }); }); - - TbMsg outMsg = null; - if (FetchTo.DATA.equals(fetchTo)) { - outMsg = TbMsg.transformMsgData(msg, JacksonUtil.toString(msgDataNode)); - } else if (FetchTo.METADATA.equals(fetchTo)) { - outMsg = TbMsg.transformMsg(msg, msgMetaData); - } - - if (failuresMap.isEmpty()) { + TbMsg outMsg = transformMessage(msg, msgDataNode, msgMetaData); + if (failuresPairSet.isEmpty()) { ctx.tellSuccess(outMsg); } else { - ctx.tellFailure(outMsg, reportFailures(failuresMap)); + ctx.tellFailure(outMsg, reportFailures(failuresPairSet)); } }, t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); } - private ListenableFuture>> getAttrAsync(TbContext ctx, EntityId entityId, String scope, List keys, ConcurrentHashMap> failuresMap) { + private ListenableFuture>> getAttrAsync( + TbContext ctx, + EntityId entityId, + String scope, + List keys, + Set>> failuresPairSet + ) { if (CollectionUtils.isEmpty(keys)) { return Futures.immediateFuture(null); } var attributeKvEntryListFuture = ctx.getAttributesService().find(ctx.getTenantId(), entityId, scope, keys); return Futures.transform(attributeKvEntryListFuture, attributeKvEntryList -> { if (isTellFailureIfAbsent && attributeKvEntryList.size() != keys.size()) { - getNotExistingKeys(attributeKvEntryList, keys).forEach(key -> computeFailuresMap(scope, failuresMap, key)); + List nonExistentKeys = getNonExistentKeys(attributeKvEntryList, keys); + failuresPairSet.add(new TbPair<>(scope, nonExistentKeys)); } - var mapAttributeKvEntry = new HashMap>(); - mapAttributeKvEntry.put(scope, attributeKvEntryList); - return mapAttributeKvEntry; + return new TbPair<>(scope, attributeKvEntryList); }, MoreExecutors.directExecutor()); } - private ListenableFuture>> getLatestTelemetry(TbContext ctx, EntityId entityId, List keys, ConcurrentHashMap> failuresMap) { + private ListenableFuture>> getLatestTelemetry(TbContext ctx, EntityId entityId, List keys, Set>> failuresPairSet) { if (CollectionUtils.isEmpty(keys)) { return Futures.immediateFuture(null); } ListenableFuture> latestTelemetryFutures = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, keys); return Futures.transform(latestTelemetryFutures, tsKvEntries -> { var listTsKvEntry = new ArrayList(); + var nonExistentKeys = new ArrayList(); tsKvEntries.forEach(tsKvEntry -> { if (tsKvEntry.getValue() == null) { if (isTellFailureIfAbsent) { - computeFailuresMap(LATEST_TS, failuresMap, tsKvEntry.getKey()); + nonExistentKeys.add(tsKvEntry.getKey()); } } else if (getLatestValueWithTs) { listTsKvEntry.add(getValueWithTs(tsKvEntry)); @@ -157,9 +142,10 @@ public abstract class TbAbstractGetAttributesNode>(); - mapTsKvEntry.put(LATEST_TS, listTsKvEntry); - return mapTsKvEntry; + if (isTellFailureIfAbsent && !nonExistentKeys.isEmpty()) { + failuresPairSet.add(new TbPair<>(LATEST_TS, nonExistentKeys)); + } + return new TbPair<>(LATEST_TS, listTsKvEntry); }, MoreExecutors.directExecutor()); } @@ -187,31 +173,19 @@ public abstract class TbAbstractGetAttributesNode getNotExistingKeys(List existingAttributesKvEntry, List allKeys) { + private List getNonExistentKeys(List existingAttributesKvEntry, List allKeys) { List existingKeys = existingAttributesKvEntry.stream().map(KvEntry::getKey).collect(Collectors.toList()); return allKeys.stream().filter(key -> !existingKeys.contains(key)).collect(Collectors.toList()); } - private void computeFailuresMap(String scope, ConcurrentHashMap> failuresMap, String key) { - List failures = failuresMap.computeIfAbsent(scope, k -> new ArrayList<>()); - failures.add(key); - } - - private RuntimeException reportFailures(ConcurrentHashMap> failuresMap) { + private RuntimeException reportFailures(Set>> failuresPairSet) { var errorMessage = new StringBuilder("The following attribute/telemetry keys is not present in the DB: ").append("\n"); - if (failuresMap.containsKey(CLIENT_SCOPE)) { - errorMessage.append("\t").append("[" + CLIENT_SCOPE + "]:").append(failuresMap.get(CLIENT_SCOPE).toString()).append("\n"); - } - if (failuresMap.containsKey(SERVER_SCOPE)) { - errorMessage.append("\t").append("[" + SERVER_SCOPE + "]:").append(failuresMap.get(SERVER_SCOPE).toString()).append("\n"); - } - if (failuresMap.containsKey(SHARED_SCOPE)) { - errorMessage.append("\t").append("[" + SHARED_SCOPE + "]:").append(failuresMap.get(SHARED_SCOPE).toString()).append("\n"); - } - if (failuresMap.containsKey(LATEST_TS)) { - errorMessage.append("\t").append("[" + LATEST_TS + "]:").append(failuresMap.get(LATEST_TS).toString()).append("\n"); - } - failuresMap.clear(); + failuresPairSet.forEach(failurePair -> { + String scope = failurePair.getFirst(); + List nonExistentKeys = failurePair.getSecond(); + errorMessage.append("\t").append("[").append(scope).append("]:").append(nonExistentKeys.toString()).append("\n"); + }); + failuresPairSet.clear(); return new RuntimeException(errorMessage.toString()); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java index 874cee2e75..0a650bf3d9 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java @@ -20,8 +20,8 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.kv.KvEntry; @@ -30,7 +30,6 @@ import org.thingsboard.server.common.msg.TbMsg; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.NoSuchElementException; import java.util.stream.Collectors; import static org.thingsboard.common.util.DonAsynchron.withCallback; @@ -38,35 +37,31 @@ import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; @Slf4j public abstract class TbAbstractGetEntityAttrNode extends TbAbstractNodeWithFetchTo { + @Override public void onMsg(TbContext ctx, TbMsg msg) { - ObjectNode msgDataAsJsonNode; - if (FetchTo.DATA.equals(fetchTo)) { - msgDataAsJsonNode = getMsgDataAsObjectNode(msg); - } else { - msgDataAsJsonNode = null; - } ctx.checkTenantEntity(msg.getOriginator()); + var msgDataAsObjectNode = FetchTo.DATA.equals(fetchTo) ? getMsgDataAsObjectNode(msg) : null; withCallback(findEntityAsync(ctx, msg.getOriginator()), - entityId -> safeGetAttributes(ctx, msg, entityId, msgDataAsJsonNode), + entityId -> safeGetAttributes(ctx, msg, entityId, msgDataAsObjectNode), t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); } protected abstract ListenableFuture findEntityAsync(TbContext ctx, EntityId originator); - private void safeGetAttributes(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) { - if (entityId == null || entityId.isNullUid()) { - ctx.tellFailure(msg, new NoSuchElementException("Did not find entity! Msg ID: " + msg.getId())); - return; + protected void checkIfMappingIsNotEmptyOrThrow(TbGetEntityAttrNodeConfiguration config) throws TbNodeException { + if (config.getAttrMapping().isEmpty()) { + throw new TbNodeException("At least one attribute mapping should be specified!"); } + } - Map mappingsMap = new HashMap<>(); + private void safeGetAttributes(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) { + var mappingsMap = new HashMap(); config.getAttrMapping().forEach((key, value) -> { String patternProcessedSourceKey = TbNodeUtils.processPattern(key, msg); String patternProcessedTargetKey = TbNodeUtils.processPattern(value, msg); mappingsMap.put(patternProcessedSourceKey, patternProcessedTargetKey); }); - var sourceKeys = List.copyOf(mappingsMap.keySet()); withCallback(config.isTelemetry() ? getLatestTelemetryAsync(ctx, entityId, sourceKeys) : getAttributesAsync(ctx, entityId, sourceKeys), data -> putDataAndTell(ctx, msg, data, mappingsMap, msgDataAsJsonNode), @@ -91,20 +86,13 @@ public abstract class TbAbstractGetEntityAttrNode extends Tb MoreExecutors.directExecutor()); } - private void putDataAndTell(TbContext ctx, TbMsg msg, List data, Map map, ObjectNode msgDataAsJsonNode) { + private void putDataAndTell(TbContext ctx, TbMsg msg, List data, Map map, ObjectNode msgData) { + var msgMetaData = msg.getMetaData().copy(); for (KvEntry entry : data) { String targetKey = map.get(entry.getKey()); - String value = entry.getValueAsString(); - if (FetchTo.DATA.equals(fetchTo)) { - msgDataAsJsonNode.put(targetKey, value); - } else if (FetchTo.METADATA.equals(fetchTo)) { - msg.getMetaData().putValue(targetKey, value); - } - } - if (FetchTo.DATA.equals(fetchTo)) { - ctx.tellSuccess(TbMsg.transformMsgData(msg, JacksonUtil.toString(msgDataAsJsonNode))); - } else if (FetchTo.METADATA.equals(fetchTo)) { - ctx.tellSuccess(msg); + enrichMessage(msgData, msgMetaData, entry, targetKey); } + ctx.tellSuccess(transformMessage(msg, msgData, msgMetaData)); } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java index 4644db2ff7..0016234a91 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNode.java @@ -15,159 +15,131 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.reflect.TypeToken; -import lombok.AllArgsConstructor; -import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.rule.engine.util.EntityDetails; +import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.ContactBased; +import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; -import java.lang.reflect.Type; -import java.util.Map; - import static org.thingsboard.common.util.DonAsynchron.withCallback; @Slf4j -public abstract class TbAbstractGetEntityDetailsNode extends TbAbstractNodeWithFetchTo { - private static final Gson gson = new Gson(); - private static final Type TYPE = new TypeToken>() { - }.getType(); +public abstract class TbAbstractGetEntityDetailsNode extends TbAbstractNodeWithFetchTo { @Override public void onMsg(TbContext ctx, TbMsg msg) { - withCallback(getDetails(ctx, msg), + ctx.checkTenantEntity(msg.getOriginator()); + var msgDataAsObjectNode = FetchTo.DATA.equals(fetchTo) ? getMsgDataAsObjectNode(msg) : null; + withCallback(getDetails(ctx, msg, msgDataAsObjectNode), ctx::tellSuccess, t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); } - protected abstract ListenableFuture getDetails(TbContext ctx, TbMsg msg); + protected abstract String getPrefix(); - protected abstract ListenableFuture getContactBasedListenableFuture(TbContext ctx, TbMsg msg); + protected abstract ListenableFuture> getContactBasedFuture(TbContext ctx, TbMsg msg); - protected MessageData getDataAsJson(TbMsg msg) { - if (fetchTo == FetchTo.METADATA) { - return new MessageData(gson.toJsonTree(msg.getMetaData().getData(), TYPE), DataSource.METADATA); - } else if (fetchTo == FetchTo.DATA) { - var msgDataJsonElement = JsonParser.parseString(msg.getData()); - if (!msgDataJsonElement.isJsonObject()) { - throw new IllegalArgumentException("Message body is not an object!"); - } - return new MessageData(msgDataJsonElement, DataSource.DATA); - } else { - throw new IllegalArgumentException("Unsupported fetchTo value!"); + protected void checkIfDetailsListIsNotEmptyOrThrow(C configuration) throws TbNodeException { + if (configuration.getDetailsList().isEmpty()) { + throw new TbNodeException("No entity details selected!"); } } - protected ListenableFuture getTbMsgListenableFuture(TbContext ctx, TbMsg msg, MessageData messageData, String prefix) { - if (config.getDetailsList().isEmpty()) { - return Futures.immediateFuture(msg); - } else { - ListenableFuture contactBasedListenableFuture = getContactBasedListenableFuture(ctx, msg); - ListenableFuture resultObject = addContactProperties(messageData.getData(), contactBasedListenableFuture, prefix); - return transformMsg(ctx, msg, resultObject, messageData); - } - } - - private ListenableFuture transformMsg(TbContext ctx, TbMsg msg, ListenableFuture propertiesFuture, MessageData messageData) { - return Futures.transformAsync(propertiesFuture, jsonElement -> { - if (jsonElement == null) { - return Futures.immediateFuture(null); - } else if (messageData.getDataSource().equals(DataSource.METADATA)) { - Map metadataMap = gson.fromJson(jsonElement.toString(), TYPE); - return Futures.immediateFuture(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), new TbMsgMetaData(metadataMap), msg.getData())); - } else { - return Futures.immediateFuture(ctx.transformMsg(msg, msg.getType(), msg.getOriginator(), msg.getMetaData(), gson.toJson(jsonElement))); - } - }, MoreExecutors.directExecutor()); - } - - private ListenableFuture addContactProperties(JsonElement data, ListenableFuture entityFuture, String prefix) { - return Futures.transformAsync(entityFuture, contactBased -> { + private ListenableFuture getDetails(TbContext ctx, TbMsg msg, ObjectNode messageData) { + ListenableFuture> contactBasedFuture = getContactBasedFuture(ctx, msg); + return Futures.transformAsync(contactBasedFuture, contactBased -> { if (contactBased == null) { - return Futures.immediateFuture(null); - } else { - JsonElement jsonElement = null; - for (EntityDetails entityDetails : this.config.getDetailsList()) { - jsonElement = setProperties(contactBased, data, entityDetails, prefix); - } - return Futures.immediateFuture(jsonElement); + return Futures.immediateFuture(msg); } + var msgMetaData = msg.getMetaData().copy(); + setProperties(contactBased, messageData, msgMetaData); + return Futures.immediateFuture(transformMessage(msg, messageData, msgMetaData)); }, MoreExecutors.directExecutor()); } - private JsonElement setProperties(ContactBased entity, JsonElement data, EntityDetails entityDetails, String prefix) { - JsonObject dataAsObject = data.getAsJsonObject(); - switch (entityDetails) { - case ID: - dataAsObject.addProperty(prefix + "id", entity.getId().toString()); - break; - case TITLE: - dataAsObject.addProperty(prefix + "title", entity.getName()); - break; - case ADDRESS: - if (entity.getAddress() != null) { - dataAsObject.addProperty(prefix + "address", entity.getAddress()); - } - break; - case ADDRESS2: - if (entity.getAddress2() != null) { - dataAsObject.addProperty(prefix + "address2", entity.getAddress2()); - } - break; - case CITY: - if (entity.getCity() != null) dataAsObject.addProperty(prefix + "city", entity.getCity()); - break; - case COUNTRY: - if (entity.getCountry() != null) - dataAsObject.addProperty(prefix + "country", entity.getCountry()); - break; - case STATE: - if (entity.getState() != null) { - dataAsObject.addProperty(prefix + "state", entity.getState()); - } - break; - case EMAIL: - if (entity.getEmail() != null) { - dataAsObject.addProperty(prefix + "email", entity.getEmail()); - } - break; - case PHONE: - if (entity.getPhone() != null) { - dataAsObject.addProperty(prefix + "phone", entity.getPhone()); - } - break; - case ZIP: - if (entity.getZip() != null) { - dataAsObject.addProperty(prefix + "zip", entity.getZip()); - } - break; - case ADDITIONAL_INFO: - if (entity.getAdditionalInfo().hasNonNull("description")) { - dataAsObject.addProperty(prefix + "additionalInfo", entity.getAdditionalInfo().get("description").asText()); - } - break; + private void setProperties(ContactBased contactBased, ObjectNode messageData, TbMsgMetaData msgMetaData) { + String prefix = getPrefix(); + String property; + String value; + for (var entityDetails : config.getDetailsList()) { + switch (entityDetails) { + case ID: + property = prefix + "id"; + value = contactBased.getId().getId().toString(); + setDetail(property, value, messageData, msgMetaData); + break; + case TITLE: + property = prefix + "title"; + value = contactBased.getName(); + setDetail(property, value, messageData, msgMetaData); + break; + case ADDRESS: + property = prefix + "address"; + value = contactBased.getAddress(); + setDetail(property, value, messageData, msgMetaData); + break; + case ADDRESS2: + property = prefix + "address2"; + value = contactBased.getAddress2(); + setDetail(property, value, messageData, msgMetaData); + break; + case CITY: + property = prefix + "city"; + value = contactBased.getCity(); + setDetail(property, value, messageData, msgMetaData); + break; + case COUNTRY: + property = prefix + "country"; + value = contactBased.getCountry(); + setDetail(property, value, messageData, msgMetaData); + break; + case STATE: + property = prefix + "state"; + value = contactBased.getState(); + setDetail(property, value, messageData, msgMetaData); + break; + case EMAIL: + property = prefix + "email"; + value = contactBased.getEmail(); + setDetail(property, value, messageData, msgMetaData); + break; + case PHONE: + property = prefix + "phone"; + value = contactBased.getPhone(); + setDetail(property, value, messageData, msgMetaData); + break; + case ZIP: + property = prefix + "zip"; + value = contactBased.getZip(); + setDetail(property, value, messageData, msgMetaData); + break; + case ADDITIONAL_INFO: + if (contactBased.getAdditionalInfo().hasNonNull("description")) { + property = prefix + "additionalInfo"; + value = contactBased.getAdditionalInfo().get("description").asText(); + setDetail(property, value, messageData, msgMetaData); + } + break; + } } - return dataAsObject; } - @Data - @AllArgsConstructor - private static class MessageData { - private JsonElement data; - private DataSource dataSource; + private void setDetail(String property, String value, ObjectNode messageData, TbMsgMetaData msgMetaData) { + if (value == null) { + return; + } + if (FetchTo.METADATA.equals(fetchTo)) { + msgMetaData.putValue(property, value); + } + if (FetchTo.DATA.equals(fetchTo)) { + messageData.put(property, value); + } } - private enum DataSource { - DATA, METADATA - } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java index 1da798ae82..4bf150ebff 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDetailsNodeConfiguration.java @@ -24,5 +24,7 @@ import java.util.List; @Data @EqualsAndHashCode(callSuper = true) public abstract class TbAbstractGetEntityDetailsNodeConfiguration extends TbAbstractFetchToNodeConfiguration { + private List detailsList; + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java index 3cf6300b77..a9c204215c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java @@ -17,14 +17,24 @@ package org.thingsboard.rule.engine.metadata; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.util.concurrent.AsyncFunction; +import com.google.common.util.concurrent.Futures; +import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgMetaData; +import java.util.NoSuchElementException; + +@Slf4j public abstract class TbAbstractNodeWithFetchTo implements TbNode { + protected C config; protected FetchTo fetchTo; @@ -32,7 +42,7 @@ public abstract class TbAbstractNodeWithFetchTo AsyncFunction checkIfEntityIsPresentOrThrow(String message) { + return id -> { + if (id == null || id.isNullUid()) { + return Futures.immediateFailedFuture(new NoSuchElementException(message)); + } + return Futures.immediateFuture(id); + }; + } + protected ObjectNode getMsgDataAsObjectNode(TbMsg msg) { JsonNode msgDataNode = JacksonUtil.toJsonNode(msg.getData()); - if (!msgDataNode.isObject()) { + if (msgDataNode == null || !msgDataNode.isObject()) { throw new IllegalArgumentException("Message body is not an object!"); } return (ObjectNode) msgDataNode; } + + protected void enrichMessage(ObjectNode msgData, TbMsgMetaData metaData, KvEntry kvEntry, String targetKey) { + if (FetchTo.DATA.equals(fetchTo)) { + JacksonUtil.addKvEntry(msgData, kvEntry, targetKey); + } else if (FetchTo.METADATA.equals(fetchTo)) { + metaData.putValue(targetKey, kvEntry.getValueAsString()); + } + } + + protected TbMsg transformMessage(TbMsg msg, ObjectNode msgDataNode, TbMsgMetaData msgMetaData) { + switch (fetchTo) { + case DATA: + return TbMsg.transformMsgData(msg, JacksonUtil.toString(msgDataNode)); + case METADATA: + return TbMsg.transformMsg(msg, msgMetaData); + default: + log.debug("Unexpected FetchTo value: {}. Allowed values: {}", fetchTo, FetchTo.values()); + return msg; + } + } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java index 0a8ca6b255..f1dba47a90 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RuleNode; @@ -43,6 +44,7 @@ import java.util.concurrent.ExecutionException; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeFetchDeviceCredentialsConfig") public class TbFetchDeviceCredentialsNode extends TbAbstractNodeWithFetchTo { + private static final String CREDENTIALS = "credentials"; private static final String CREDENTIALS_TYPE = "credentialsType"; @@ -55,6 +57,7 @@ public class TbFetchDeviceCredentialsNode extends TbAbstractNodeWithFetchTo findEntityIdAsync(TbContext ctx, TbMsg msg) { - ctx.checkTenantEntity(msg.getOriginator()); return Futures.immediateFuture(msg.getOriginator()); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java index 89c4eb8086..2450796b59 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeConfiguration.java @@ -28,6 +28,7 @@ import java.util.List; @Data @EqualsAndHashCode(callSuper = true) public class TbGetAttributesNodeConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { + private List clientAttributeNames; private List sharedAttributeNames; private List serverAttributeNames; @@ -49,4 +50,5 @@ public class TbGetAttributesNodeConfiguration extends TbAbstractFetchToNodeConfi configuration.setFetchTo(FetchTo.METADATA); return configuration; } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index d00de4dd0e..5f5f73c01c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.metadata; +import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; @@ -30,22 +31,30 @@ import org.thingsboard.server.common.data.plugin.ComponentType; type = ComponentType.ENRICHMENT, name = "customer attributes", configClazz = TbGetEntityAttrNodeConfiguration.class, - nodeDescription = "Add Originators Customer Attributes or Latest Telemetry into Message Metadata/Data", - nodeDetails = "Enrich the Message Metadata/Data with the corresponding customer's latest attributes or telemetry value. " + + nodeDescription = "Add Originators Customer Attributes or Latest Telemetry into Message or Metadata", + nodeDetails = "Enrich the Message or Metadata with the corresponding customer's latest attributes or telemetry value. " + "The customer is selected based on the originator of the message: device, asset, etc. " + "
" + "Useful when you store some parameters on the customer level and would like to use them for message processing.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeCustomerAttributesConfig") public class TbGetCustomerAttributeNode extends TbAbstractGetEntityAttrNode { + + private static final String CUSTOMER_NOT_FOUND_MESSAGE = "Failed to find customer for entity with id %s and type %s"; + @Override - protected ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { - ctx.checkTenantEntity(originator); - return EntitiesCustomerIdAsyncLoader.findEntityIdAsync(ctx, originator); + protected TbGetEntityAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + var config = TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); + checkIfMappingIsNotEmptyOrThrow(config); + return config; } @Override - protected TbGetEntityAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - return TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); + protected ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { + return Futures.transformAsync(EntitiesCustomerIdAsyncLoader.findEntityIdAsync(ctx, originator), + checkIfEntityIsPresentOrThrow(String.format(CUSTOMER_NOT_FOUND_MESSAGE, originator.getId(), originator.getEntityType().getNormalName())), + ctx.getDbCallbackExecutor() + ); } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index 1d7c53e002..810a6c2cd3 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.id.AssetId; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; @@ -37,6 +38,8 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; +import java.util.NoSuchElementException; + @Slf4j @RuleNode(type = ComponentType.ENRICHMENT, name = "customer details", @@ -47,28 +50,24 @@ import org.thingsboard.server.common.msg.TbMsg; "If the originator of the message is not assigned to Customer, or originator type is not supported - Message will be forwarded to Failure chain, otherwise, Success chain will be used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeEntityDetailsConfig") -public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode { +public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode { + private static final String CUSTOMER_PREFIX = "customer_"; @Override protected TbGetCustomerDetailsNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - return TbNodeUtils.convert(configuration, TbGetCustomerDetailsNodeConfiguration.class); + var config = TbNodeUtils.convert(configuration, TbGetCustomerDetailsNodeConfiguration.class); + checkIfDetailsListIsNotEmptyOrThrow(config); + return config; } @Override - protected ListenableFuture getDetails(TbContext ctx, TbMsg msg) { - ctx.checkTenantEntity(msg.getOriginator()); - return getTbMsgListenableFuture(ctx, msg, getDataAsJson(msg), CUSTOMER_PREFIX); + protected String getPrefix() { + return CUSTOMER_PREFIX; } @Override - protected ListenableFuture getContactBasedListenableFuture(TbContext ctx, TbMsg msg) { - return Futures.transformAsync(getCustomer(ctx, msg), customer -> - customer == null ? Futures.immediateFuture(null) : Futures.immediateFuture(customer), - MoreExecutors.directExecutor()); - } - - private ListenableFuture getCustomer(TbContext ctx, TbMsg msg) { + protected ListenableFuture> getContactBasedFuture(TbContext ctx, TbMsg msg) { switch (msg.getOriginator().getEntityType()) { case DEVICE: return Futures.transformAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), new DeviceId(msg.getOriginator().getId())), @@ -86,7 +85,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode getCustomerFuture(ctx, edge, msg.getOriginator()), MoreExecutors.directExecutor()); default: - throw new RuntimeException("Entity with entityType '" + msg.getOriginator().getEntityType() + "' is not supported."); + return Futures.immediateFailedFuture(new NoSuchElementException("Entity with entityType '" + msg.getOriginator().getEntityType() + "' is not supported.")); } } @@ -96,7 +95,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode { + @Override public TbGetCustomerDetailsNodeConfiguration defaultConfiguration() { var configuration = new TbGetCustomerDetailsNodeConfiguration(); configuration.setDetailsList(Collections.emptyList()); - configuration.setFetchTo(FetchTo.METADATA); + configuration.setFetchTo(FetchTo.DATA); return configuration; } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java index 96230ae28f..fdbb412e6b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.metadata; +import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.RuleNode; @@ -39,6 +40,9 @@ import org.thingsboard.server.common.msg.TbMsg; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeDeviceAttributesConfig") public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode { + + private static final String RELATED_DEVICE_NOT_FOUND_MESSAGE = "Failed to find related device to message originator using relation query specified in the configuration!"; + @Override protected TbGetDeviceAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { return TbNodeUtils.convert(configuration, TbGetDeviceAttrNodeConfiguration.class); @@ -46,7 +50,10 @@ public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode findEntityIdAsync(TbContext ctx, TbMsg msg) { - ctx.checkTenantEntity(msg.getOriginator()); - return EntitiesRelatedDeviceIdAsyncLoader.findDeviceAsync(ctx, msg.getOriginator(), config.getDeviceRelationsQuery()); + return Futures.transformAsync( + EntitiesRelatedDeviceIdAsyncLoader.findDeviceAsync(ctx, msg.getOriginator(), config.getDeviceRelationsQuery()), + checkIfEntityIsPresentOrThrow(RELATED_DEVICE_NOT_FOUND_MESSAGE), + ctx.getDbCallbackExecutor()); } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java index 108a1f5017..60a2c9cdf7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeConfiguration.java @@ -26,6 +26,7 @@ import java.util.Collections; @Data @EqualsAndHashCode(callSuper = true) public class TbGetDeviceAttrNodeConfiguration extends TbGetAttributesNodeConfiguration { + private DeviceRelationsQuery deviceRelationsQuery; @Override @@ -49,4 +50,5 @@ public class TbGetDeviceAttrNodeConfiguration extends TbGetAttributesNodeConfigu return configuration; } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java index fccbdfb39f..18134a5040 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java @@ -25,17 +25,19 @@ import java.util.Map; @Data @EqualsAndHashCode(callSuper = true) public class TbGetEntityAttrNodeConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { + private Map attrMapping; - private boolean isTelemetry = false; + private boolean isTelemetry; @Override public TbGetEntityAttrNodeConfiguration defaultConfiguration() { var configuration = new TbGetEntityAttrNodeConfiguration(); var attrMapping = new HashMap(); - attrMapping.putIfAbsent("serialNumber", "sn"); + attrMapping.putIfAbsent("alarmThreshold", "threshold"); configuration.setAttrMapping(attrMapping); configuration.setTelemetry(false); configuration.setFetchTo(FetchTo.METADATA); return configuration; } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java index 3c0498f6ba..e5d428100b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java @@ -25,6 +25,7 @@ import java.util.Map; @Data @EqualsAndHashCode(callSuper = true) public class TbGetOriginatorFieldsConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { + private Map fieldsMapping; private boolean ignoreNullStrings; @@ -39,4 +40,5 @@ public class TbGetOriginatorFieldsConfiguration extends TbAbstractFetchToNodeCon configuration.setFetchTo(FetchTo.METADATA); return configuration; } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java index 7dee45aae0..f520425cbc 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java @@ -15,11 +15,9 @@ */ package org.thingsboard.rule.engine.metadata; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; @@ -29,8 +27,8 @@ import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgMetaData; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -48,60 +46,53 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeOriginatorFieldsConfig") public class TbGetOriginatorFieldsNode extends TbAbstractNodeWithFetchTo { + @Override protected TbGetOriginatorFieldsConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - return TbNodeUtils.convert(configuration, TbGetOriginatorFieldsConfiguration.class); + var getOriginatorFieldsConfiguration = TbNodeUtils.convert(configuration, TbGetOriginatorFieldsConfiguration.class); + if (config.getFieldsMapping().isEmpty()) { + throw new TbNodeException("At least one field mapping should be specified!"); + } + return getOriginatorFieldsConfiguration; } @Override public void onMsg(TbContext ctx, TbMsg msg) { - ObjectNode msgDataAsJsonNode; - if (FetchTo.DATA.equals(fetchTo)) { - msgDataAsJsonNode = getMsgDataAsObjectNode(msg); - } else { - msgDataAsJsonNode = null; - } ctx.checkTenantEntity(msg.getOriginator()); + var msgDataAsObjectNode = FetchTo.DATA.equals(fetchTo) ? getMsgDataAsObjectNode(msg) : null; withCallback(collectMappedEntityFieldsAsync(ctx, msg.getOriginator()), targetKeysToSourceValuesMap -> { + TbMsgMetaData msgMetaData = msg.getMetaData().copy(); for (var entry : targetKeysToSourceValuesMap.entrySet()) { var targetKeyName = entry.getKey(); var sourceFieldValue = entry.getValue(); if (FetchTo.DATA.equals(fetchTo)) { - msgDataAsJsonNode.put(targetKeyName, sourceFieldValue); + msgDataAsObjectNode.put(targetKeyName, sourceFieldValue); } else if (FetchTo.METADATA.equals(fetchTo)) { - msg.getMetaData().putValue(targetKeyName, sourceFieldValue); + msgMetaData.putValue(targetKeyName, sourceFieldValue); } } - - if (FetchTo.DATA.equals(fetchTo)) { - ctx.tellSuccess(TbMsg.transformMsgData(msg, JacksonUtil.toString(msgDataAsJsonNode))); - } else if (FetchTo.METADATA.equals(fetchTo)) { - ctx.tellSuccess(msg); - } + TbMsg outMsg = transformMessage(msg, msgDataAsObjectNode, msgMetaData); + ctx.tellSuccess(outMsg); }, t -> ctx.tellFailure(msg, t), MoreExecutors.directExecutor()); } private ListenableFuture> collectMappedEntityFieldsAsync(TbContext ctx, EntityId entityId) { - if (config.getFieldsMapping().isEmpty()) { - return Futures.immediateFuture(Collections.emptyMap()); - } else { - return Futures.transform(EntitiesFieldsAsyncLoader.findAsync(ctx, entityId), - fieldsData -> { - var targetKeysToSourceValuesMap = new HashMap(); - for (var mappingEntry : config.getFieldsMapping().entrySet()) { - var sourceFieldName = mappingEntry.getKey(); - var targetKeyName = mappingEntry.getValue(); - var sourceFieldValue = fieldsData.getFieldValue(sourceFieldName, config.isIgnoreNullStrings()); - if (sourceFieldValue != null) { - targetKeysToSourceValuesMap.put(targetKeyName, sourceFieldValue); - } + return Futures.transform(EntitiesFieldsAsyncLoader.findAsync(ctx, entityId), + fieldsData -> { + var targetKeysToSourceValuesMap = new HashMap(); + for (var mappingEntry : config.getFieldsMapping().entrySet()) { + var sourceFieldName = mappingEntry.getKey(); + var targetKeyName = mappingEntry.getValue(); + var sourceFieldValue = fieldsData.getFieldValue(sourceFieldName, config.isIgnoreNullStrings()); + if (sourceFieldValue != null) { + targetKeysToSourceValuesMap.put(targetKeyName, sourceFieldValue); } - return targetKeysToSourceValuesMap; - }, ctx.getDbCallbackExecutor() - ); - } + } + return targetKeysToSourceValuesMap; + }, ctx.getDbCallbackExecutor() + ); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java index 9387858811..26491509b8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java @@ -28,6 +28,7 @@ import java.util.HashMap; @Data @EqualsAndHashCode(callSuper = true) public class TbGetRelatedAttrNodeConfiguration extends TbGetEntityAttrNodeConfiguration { + private RelationsQuery relationsQuery; @Override @@ -37,14 +38,16 @@ public class TbGetRelatedAttrNodeConfiguration extends TbGetEntityAttrNodeConfig attrMapping.putIfAbsent("serialNumber", "sn"); configuration.setAttrMapping(attrMapping); configuration.setTelemetry(false); + configuration.setFetchTo(FetchTo.METADATA); var relationsQuery = new RelationsQuery(); + var relationEntityTypeFilter = new RelationEntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.emptyList()); relationsQuery.setDirection(EntitySearchDirection.FROM); relationsQuery.setMaxLevel(1); - var relationEntityTypeFilter = new RelationEntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.emptyList()); relationsQuery.setFilters(Collections.singletonList(relationEntityTypeFilter)); configuration.setRelationsQuery(relationsQuery); return configuration; } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index d722d1c62b..b535d050f4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.metadata; +import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; @@ -39,15 +40,23 @@ import org.thingsboard.server.common.data.plugin.ComponentType; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeRelatedAttributesConfig") public class TbGetRelatedAttributeNode extends TbAbstractGetEntityAttrNode { + + private static final String RELATED_ENTITY_NOT_FOUND_MESSAGE = "Failed to find related entity to message originator using relation query specified in the configuration!"; + @Override public TbGetRelatedAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - return TbNodeUtils.convert(configuration, TbGetRelatedAttrNodeConfiguration.class); + var config = TbNodeUtils.convert(configuration, TbGetRelatedAttrNodeConfiguration.class); + checkIfMappingIsNotEmptyOrThrow(config); + return config; } @Override public ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { - ctx.checkTenantEntity(originator); var relatedAttrConfig = (TbGetRelatedAttrNodeConfiguration) config; - return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, originator, relatedAttrConfig.getRelationsQuery()); + return Futures.transformAsync( + EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, originator, relatedAttrConfig.getRelationsQuery()), + checkIfEntityIsPresentOrThrow(RELATED_ENTITY_NOT_FOUND_MESSAGE), + ctx.getDbCallbackExecutor()); } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index dcc96e82c1..d729c6159f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -40,14 +40,17 @@ import org.thingsboard.server.common.data.plugin.ComponentType; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeTenantAttributesConfig") public class TbGetTenantAttributeNode extends TbAbstractGetEntityAttrNode { + @Override - public ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { - ctx.checkTenantEntity(originator); - return Futures.immediateFuture(ctx.getTenantId()); + public TbGetEntityAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + var config = TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); + checkIfMappingIsNotEmptyOrThrow(config); + return config; } @Override - public TbGetEntityAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - return TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); + public ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { + return Futures.immediateFuture(ctx.getTenantId()); } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index c89259d9ad..645106ab10 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -15,9 +15,7 @@ */ package org.thingsboard.rule.engine.metadata; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; @@ -25,6 +23,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.ContactBased; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; @@ -38,25 +37,25 @@ import org.thingsboard.server.common.msg.TbMsg; "If the originator of the message is not assigned to Tenant, or originator type is not supported - Message will be forwarded to Failure chain, otherwise, Success chain will be used.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeEntityDetailsConfig") -public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode { +public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode { + private static final String TENANT_PREFIX = "tenant_"; @Override protected TbGetTenantDetailsNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - return TbNodeUtils.convert(configuration, TbGetTenantDetailsNodeConfiguration.class); + var config = TbNodeUtils.convert(configuration, TbGetTenantDetailsNodeConfiguration.class); + checkIfDetailsListIsNotEmptyOrThrow(config); + return config; } @Override - protected ListenableFuture getDetails(TbContext ctx, TbMsg msg) { - ctx.checkTenantEntity(msg.getOriginator()); - return getTbMsgListenableFuture(ctx, msg, getDataAsJson(msg), TENANT_PREFIX); + protected String getPrefix() { + return TENANT_PREFIX; } @Override - protected ListenableFuture getContactBasedListenableFuture(TbContext ctx, TbMsg msg) { - ctx.checkTenantEntity(msg.getOriginator()); - return Futures.transformAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), ctx.getTenantId()), tenant -> - tenant == null ? Futures.immediateFuture(null) : Futures.immediateFuture(tenant), - MoreExecutors.directExecutor()); + protected ListenableFuture> getContactBasedFuture(TbContext ctx, TbMsg msg) { + return ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), ctx.getTenantId()); } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeConfiguration.java index e3608abbbd..c8d74c6170 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeConfiguration.java @@ -24,11 +24,13 @@ import java.util.Collections; @Data @EqualsAndHashCode(callSuper = true) public class TbGetTenantDetailsNodeConfiguration extends TbAbstractGetEntityDetailsNodeConfiguration implements NodeConfiguration { + @Override public TbGetTenantDetailsNodeConfiguration defaultConfiguration() { TbGetTenantDetailsNodeConfiguration configuration = new TbGetTenantDetailsNodeConfiguration(); configuration.setDetailsList(Collections.emptyList()); - configuration.setFetchTo(FetchTo.METADATA); + configuration.setFetchTo(FetchTo.DATA); return configuration; } + } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java index bc693d9b97..b2a1599e8c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java @@ -36,12 +36,13 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; * Created by ashvayka on 19.01.18. */ @Slf4j -public abstract class TbAbstractTransformNode implements TbNode { - private TbTransformNodeConfiguration config; +public abstract class TbAbstractTransformNode implements TbNode { + + protected C config; @Override - public void init(TbContext context, TbNodeConfiguration configuration) throws TbNodeException { - this.config = TbNodeUtils.convert(configuration, TbTransformNodeConfiguration.class); + public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { + config = loadNodeConfiguration(ctx, configuration); } @Override @@ -52,18 +53,12 @@ public abstract class TbAbstractTransformNode implements TbNode { MoreExecutors.directExecutor()); } + protected abstract C loadNodeConfiguration(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException; + protected void transformFailure(TbContext ctx, TbMsg msg, Throwable t) { ctx.tellFailure(msg, t); } - protected void transformSuccess(TbContext ctx, TbMsg msg, TbMsg m) { - if (m != null) { - ctx.tellSuccess(m); - } else { - ctx.tellFailure(msg, new RuntimeException("Message is null!")); - } - } - protected void transformSuccess(TbContext ctx, TbMsg msg, List msgs) { if (msgs != null && !msgs.isEmpty()) { if (msgs.size() == 1) { @@ -89,7 +84,4 @@ public abstract class TbAbstractTransformNode implements TbNode { protected abstract ListenableFuture> transform(TbContext ctx, TbMsg msg); - public void setConfig(TbTransformNodeConfiguration config) { - this.config = config; - } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java index 911b811032..5cc5dfe23f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java @@ -37,6 +37,7 @@ import org.thingsboard.server.common.msg.TbMsg; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.NoSuchElementException; @Slf4j @RuleNode( @@ -51,31 +52,36 @@ import java.util.List; configDirective = "tbTransformationNodeChangeOriginatorConfig", icon = "find_replace" ) -public class TbChangeOriginatorNode extends TbAbstractTransformNode { +public class TbChangeOriginatorNode extends TbAbstractTransformNode { - protected static final String CUSTOMER_SOURCE = "CUSTOMER"; - protected static final String TENANT_SOURCE = "TENANT"; - protected static final String RELATED_SOURCE = "RELATED"; - protected static final String ALARM_ORIGINATOR_SOURCE = "ALARM_ORIGINATOR"; - protected static final String ENTITY_SOURCE = "ENTITY"; - - private TbChangeOriginatorNodeConfiguration config; + private static final String CUSTOMER_SOURCE = "CUSTOMER"; + private static final String TENANT_SOURCE = "TENANT"; + private static final String RELATED_SOURCE = "RELATED"; + private static final String ALARM_ORIGINATOR_SOURCE = "ALARM_ORIGINATOR"; + private static final String ENTITY_SOURCE = "ENTITY"; @Override - public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.config = TbNodeUtils.convert(configuration, TbChangeOriginatorNodeConfiguration.class); + protected TbChangeOriginatorNodeConfiguration loadNodeConfiguration(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { + var config = TbNodeUtils.convert(configuration, TbChangeOriginatorNodeConfiguration.class); validateConfig(config); - setConfig(config); + return config; } @Override protected ListenableFuture> transform(TbContext ctx, TbMsg msg) { - ListenableFuture newOriginator = getNewOriginator(ctx, msg); - return Futures.transform(newOriginator, n -> { - if (n == null || n.isNullUid()) { - return null; + ListenableFuture newOriginatorFuture = getNewOriginator(ctx, msg); + return Futures.transformAsync(newOriginatorFuture, newOriginator -> { + if (newOriginator == null || newOriginator.isNullUid()) { + return Futures.immediateFailedFuture(new NoSuchElementException("Failed to find new originator!")); } - return Collections.singletonList((ctx.transformMsg(msg, msg.getType(), n, msg.getMetaData(), msg.getData()))); + return Futures.immediateFuture( + Collections.singletonList( + ctx.transformMsg( + msg, + msg.getType(), + newOriginator, + msg.getMetaData(), + msg.getData()))); }, ctx.getDbCallbackExecutor()); } @@ -129,7 +135,6 @@ public class TbChangeOriginatorNode extends TbAbstractTransformNode { } EntitiesByNameAndTypeLoader.checkEntityType(EntityType.valueOf(conf.getEntityType())); } - } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeConfiguration.java index cc85933a48..473e83b91c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeConfiguration.java @@ -25,7 +25,9 @@ import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; import java.util.Collections; @Data -public class TbChangeOriginatorNodeConfiguration extends TbTransformNodeConfiguration implements NodeConfiguration { +public class TbChangeOriginatorNodeConfiguration implements NodeConfiguration { + + private static final String CUSTOMER_SOURCE = "CUSTOMER"; private String originatorSource; @@ -36,7 +38,7 @@ public class TbChangeOriginatorNodeConfiguration extends TbTransformNodeConfigur @Override public TbChangeOriginatorNodeConfiguration defaultConfiguration() { TbChangeOriginatorNodeConfiguration configuration = new TbChangeOriginatorNodeConfiguration(); - configuration.setOriginatorSource(TbChangeOriginatorNode.CUSTOMER_SOURCE); + configuration.setOriginatorSource(CUSTOMER_SOURCE); RelationsQuery relationsQuery = new RelationsQuery(); relationsQuery.setDirection(EntitySearchDirection.FROM); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java index 5c55cfb46d..ba78970c54 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNode.java @@ -43,17 +43,16 @@ import java.util.List; uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbTransformationNodeScriptConfig" ) -public class TbTransformMsgNode extends TbAbstractTransformNode { +public class TbTransformMsgNode extends TbAbstractTransformNode { - private TbTransformMsgNodeConfiguration config; private ScriptEngine scriptEngine; @Override - public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.config = TbNodeUtils.convert(configuration, TbTransformMsgNodeConfiguration.class); + protected TbTransformMsgNodeConfiguration loadNodeConfiguration(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { + var config = TbNodeUtils.convert(configuration, TbTransformMsgNodeConfiguration.class); scriptEngine = ctx.createScriptEngine(config.getScriptLang(), ScriptLanguage.TBEL.equals(config.getScriptLang()) ? config.getTbelScript() : config.getJsScript()); - setConfig(config); + return config; } @Override @@ -62,12 +61,6 @@ public class TbTransformMsgNode extends TbAbstractTransformNode { return scriptEngine.executeUpdateAsync(msg); } - @Override - protected void transformSuccess(TbContext ctx, TbMsg msg, TbMsg m) { - ctx.logJsEvalResponse(); - super.transformSuccess(ctx, msg, m); - } - @Override protected void transformFailure(TbContext ctx, TbMsg msg, Throwable t) { ctx.logJsEvalFailure(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNodeConfiguration.java index 2d4aeac161..34d465f49c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformMsgNodeConfiguration.java @@ -20,7 +20,7 @@ import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.script.ScriptLanguage; @Data -public class TbTransformMsgNodeConfiguration extends TbTransformNodeConfiguration implements NodeConfiguration { +public class TbTransformMsgNodeConfiguration implements NodeConfiguration { private ScriptLanguage scriptLang; private String jsScript; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformNodeConfiguration.java deleted file mode 100644 index 160bd6d8d1..0000000000 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbTransformNodeConfiguration.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.rule.engine.transform; - -import lombok.Data; - -@Data -public class TbTransformNodeConfiguration { - -} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesCustomerIdAsyncLoader.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesCustomerIdAsyncLoader.java index d36162196e..52fb011614 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesCustomerIdAsyncLoader.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesCustomerIdAsyncLoader.java @@ -29,9 +29,7 @@ import org.thingsboard.server.common.data.id.UserId; public class EntitiesCustomerIdAsyncLoader { - public static ListenableFuture findEntityIdAsync(TbContext ctx, EntityId original) { - switch (original.getEntityType()) { case CUSTOMER: return Futures.immediateFuture((CustomerId) original); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java index 0d54e5ddc1..15dd7f85b1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java @@ -17,8 +17,6 @@ package org.thingsboard.rule.engine.util; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; -import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.BaseData; @@ -34,36 +32,37 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UserId; +import java.util.NoSuchElementException; import java.util.function.Function; -@Slf4j public class EntitiesFieldsAsyncLoader { + public static ListenableFuture findAsync(TbContext ctx, EntityId originatorId) { switch (originatorId.getEntityType()) { case TENANT: return toEntityFieldsDataAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), (TenantId) originatorId), - EntityFieldsData::new); + EntityFieldsData::new, ctx); case CUSTOMER: return toEntityFieldsDataAsync(ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), (CustomerId) originatorId), - EntityFieldsData::new); + EntityFieldsData::new, ctx); case USER: return toEntityFieldsDataAsync(ctx.getUserService().findUserByIdAsync(ctx.getTenantId(), (UserId) originatorId), - EntityFieldsData::new); + EntityFieldsData::new, ctx); case ASSET: return toEntityFieldsDataAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), (AssetId) originatorId), - EntityFieldsData::new); + EntityFieldsData::new, ctx); case DEVICE: return toEntityFieldsDataAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), (DeviceId) originatorId), - EntityFieldsData::new); + EntityFieldsData::new, ctx); case ALARM: return toEntityFieldsDataAsync(ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), (AlarmId) originatorId), - EntityFieldsData::new); + EntityFieldsData::new, ctx); case RULE_CHAIN: return toEntityFieldsDataAsync(ctx.getRuleChainService().findRuleChainByIdAsync(ctx.getTenantId(), (RuleChainId) originatorId), - EntityFieldsData::new); + EntityFieldsData::new, ctx); case ENTITY_VIEW: return toEntityFieldsDataAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), (EntityViewId) originatorId), - EntityFieldsData::new); + EntityFieldsData::new, ctx); default: return Futures.immediateFailedFuture(new TbNodeException("Unexpected originator EntityType: " + originatorId.getEntityType())); } @@ -71,10 +70,12 @@ public class EntitiesFieldsAsyncLoader { private static > ListenableFuture toEntityFieldsDataAsync( ListenableFuture future, - Function converter + Function converter, + TbContext ctx ) { return Futures.transformAsync(future, in -> in != null ? Futures.immediateFuture(converter.apply(in)) - : Futures.immediateFailedFuture(new TbNodeException("Entity not found!")), MoreExecutors.directExecutor()); + : Futures.immediateFailedFuture(new NoSuchElementException("Entity not found!")), ctx.getDbCallbackExecutor()); } + } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeTest.java index 1f7057050e..6af846d36d 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeTest.java @@ -53,6 +53,8 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE; @RunWith(MockitoJUnitRunner.class) public class TbChangeOriginatorNodeTest { + private static final String CUSTOMER_SOURCE = "CUSTOMER"; + private TbChangeOriginatorNode node; @Mock @@ -158,7 +160,7 @@ public class TbChangeOriginatorNodeTest { public void init() throws TbNodeException { TbChangeOriginatorNodeConfiguration config = new TbChangeOriginatorNodeConfiguration(); - config.setOriginatorSource(TbChangeOriginatorNode.CUSTOMER_SOURCE); + config.setOriginatorSource(CUSTOMER_SOURCE); ObjectMapper mapper = new ObjectMapper(); TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(mapper.valueToTree(config)); From b43c28800102c85851f671d976f3e20f352c90b4 Mon Sep 17 00:00:00 2001 From: kalytka Date: Tue, 11 Apr 2023 17:04:39 +0300 Subject: [PATCH 015/207] Changes for the enrichment rule nodes --- .../relation/relation-filters.component.html | 35 +++++++---------- .../relation/relation-filters.component.scss | 38 +++++++++++++------ .../entity/entity-subtype-list.component.html | 11 +++++- .../entity/entity-subtype-list.component.ts | 13 +++++-- .../entity/entity-type-list.component.html | 3 +- .../relation-type-autocomplete.component.html | 8 ++-- .../relation-type-autocomplete.component.ts | 3 ++ .../rulenode/customer_attributes_node_fn.md | 24 ++++++++++++ .../assets/locale/locale.constant-en_US.json | 2 + 9 files changed, 95 insertions(+), 42 deletions(-) create mode 100644 ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fn.md diff --git a/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html b/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html index 16222675db..d5dfca3e71 100644 --- a/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html +++ b/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html @@ -17,28 +17,21 @@ -->

-
-
- relation.type - entity.entity-types -   -
-
-
- - - - +
+ + + + +
-
@@ -56,14 +48,13 @@ class="tb-prompt" translate>relation.any-relation
-
diff --git a/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss b/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss index b18f226f4f..d2bb8191c1 100644 --- a/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss +++ b/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss @@ -22,26 +22,40 @@ width: 100%; } - .header { - padding: 0 5px 5px; - - .cell { - padding-right: 5px; - padding-left: 5px; - font-size: 12px; - font-weight: 700; - color: rgba(0, 0, 0, .54); - white-space: nowrap; - } + .map-label { + font-weight: 400; + font-size: 12px; } + + //.header { + // padding: 0 5px 5px; + // + // .cell { + // padding-right: 5px; + // padding-left: 5px; + // font-size: 12px; + // font-weight: 700; + // color: rgba(0, 0, 0, .54); + // white-space: nowrap; + // } + //} + .body { - padding: 0 5px 20px; + //padding: 0 5px 20px; max-height: 300px; overflow: auto; .row { padding-top: 5px; + + .input-block { + border: 1px solid #E0E0E0; + border-radius: 6px; + padding: 24px 24px 2px 24px; + align-items: center; + margin: 0px 8px 15px 0px; + } } .cell { diff --git a/ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.html b/ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.html index 7d45b5a071..909d780e45 100644 --- a/ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.html +++ b/ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.html @@ -15,7 +15,8 @@ limitations under the License. --> - + + {{ label | translate }} + = 0) { @@ -249,9 +258,7 @@ export class EntitySubTypeListComponent implements ControlValueAccessor, OnInit, this.searchText = searchText; return this.getEntitySubtypes().pipe( map(subTypes => { - let result = subTypes.filter( subType => { - return searchText ? subType.toUpperCase().startsWith(searchText.toUpperCase()) : true; - }); + let result = subTypes.filter( subType => searchText ? subType.toUpperCase().startsWith(searchText.toUpperCase()) : true); if (!result.length) { result = [searchText]; } diff --git a/ui-ngx/src/app/shared/components/entity/entity-type-list.component.html b/ui-ngx/src/app/shared/components/entity/entity-type-list.component.html index 7a20291a0a..6852f7f62d 100644 --- a/ui-ngx/src/app/shared/components/entity/entity-type-list.component.html +++ b/ui-ngx/src/app/shared/components/entity/entity-type-list.component.html @@ -15,7 +15,8 @@ limitations under the License. --> - + + {{ 'entity.entity-types' | translate }} - - {{ 'relation.relation-type' | translate }} + + {{ label | translate }}
-
+
- +
+ + + +
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts index 27291b49b9..8f599d8715 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts @@ -24,13 +24,14 @@ import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; import { Widget, widgetTypesData } from '@shared/models/widget.models'; import { Dashboard } from '@app/shared/models/dashboard.models'; -import { IAliasController } from '@core/api/widget-api.models'; +import { IAliasController, IStateController } from '@core/api/widget-api.models'; import { WidgetConfigComponentData, WidgetInfo } from '@home/models/widget-component.models'; import { isDefined, isString } from '@core/utils'; export interface AddWidgetDialogData { dashboard: Dashboard; aliasController: IAliasController; + stateController: IStateController; widget: Widget; widgetInfo: WidgetInfo; } @@ -48,8 +49,11 @@ export class AddWidgetDialogComponent extends DialogComponent, @@ -62,6 +66,7 @@ export class AddWidgetDialogComponent extends DialogComponent + [isReadOnly]="true" + (closeDetails)="onEditWidgetClosed()">
+ [widgetLayout]="editingWidgetLayout" + (revertWidgetConfig)="onRevertWidgetEdit()" + (applyWidgetConfig)="saveWidget()"> +
+ + + +
+ +
+ +
+
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts index a9f6805a98..756709966f 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts @@ -14,13 +14,22 @@ /// limitations under the License. /// -import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + Input, + OnChanges, + OnInit, + Output, + SimpleChanges +} from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { MatDialog } from '@angular/material/dialog'; import { Dashboard, WidgetLayout } from '@shared/models/dashboard.models'; -import { IAliasController } from '@core/api/widget-api.models'; +import { IAliasController, IStateController } from '@core/api/widget-api.models'; import { Widget } from '@shared/models/widget.models'; import { WidgetComponentService } from '@home/components/widget/widget-component.service'; import { WidgetConfigComponentData } from '../../models/widget-component.models'; @@ -40,6 +49,9 @@ export class EditWidgetComponent extends PageComponent implements OnInit, OnChan @Input() aliasController: IAliasController; + @Input() + stateController: IStateController; + @Input() widgetEditMode: boolean; @@ -49,10 +61,18 @@ export class EditWidgetComponent extends PageComponent implements OnInit, OnChan @Input() widgetLayout: WidgetLayout; + @Output() + applyWidgetConfig = new EventEmitter(); + + @Output() + revertWidgetConfig = new EventEmitter(); + widgetFormGroup: UntypedFormGroup; widgetConfig: WidgetConfigComponentData; + previewMode = false; + constructor(protected store: Store, private dialog: MatDialog, private fb: UntypedFormBuilder, @@ -78,10 +98,21 @@ export class EditWidgetComponent extends PageComponent implements OnInit, OnChan } } if (reloadConfig) { + this.previewMode = false; this.loadWidgetConfig(); } } + onApplyWidgetConfig() { + if (this.widgetFormGroup.valid) { + this.applyWidgetConfig.emit(); + } + } + + onRevertWidgetConfig() { + this.revertWidgetConfig.emit(); + } + private loadWidgetConfig() { if (!this.widget) { return; diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index ffa2d11b99..97af82981c 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -36,7 +36,6 @@ import { EditAttributeValuePanelComponent } from '@home/components/attribute/edi import { DashboardComponent } from '@home/components/dashboard/dashboard.component'; import { WidgetComponent } from '@home/components/widget/widget.component'; import { WidgetComponentService } from '@home/components/widget/widget-component.service'; -import { LegendComponent } from '@home/components/widget/legend.component'; import { AliasesEntitySelectPanelComponent } from '@home/components/alias/aliases-entity-select-panel.component'; import { AliasesEntitySelectComponent } from '@home/components/alias/aliases-entity-select.component'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; @@ -49,7 +48,6 @@ import { EntityAliasSelectComponent } from '@home/components/alias/entity-alias- import { DataKeysComponent } from '@home/components/widget/data-keys.component'; import { DataKeyConfigDialogComponent } from '@home/components/widget/data-key-config-dialog.component'; import { DataKeyConfigComponent } from '@home/components/widget/data-key-config.component'; -import { LegendConfigComponent } from '@home/components/widget/legend-config.component'; import { ManageWidgetActionsComponent } from '@home/components/widget/action/manage-widget-actions.component'; import { WidgetActionDialogComponent } from '@home/components/widget/action/widget-action-dialog.component'; import { CustomActionPrettyResourcesTabsComponent } from '@home/components/widget/action/custom-action-pretty-resources-tabs.component'; @@ -182,6 +180,7 @@ import { AlarmFilterConfigComponent } from '@home/components/alarm/alarm-filter- import { AlarmAssigneeSelectPanelComponent } from '@home/components/alarm/alarm-assignee-select-panel.component'; import { AlarmAssigneeSelectComponent } from '@home/components/alarm/alarm-assignee-select.component'; import { DeviceInfoFilterComponent } from '@home/components/device/device-info-filter.component'; +import { WidgetPreviewComponent } from '@home/components/widget/widget-preview.component'; @NgModule({ declarations: @@ -220,16 +219,15 @@ import { DeviceInfoFilterComponent } from '@home/components/device/device-info-f DashboardComponent, WidgetContainerComponent, WidgetComponent, - LegendComponent, WidgetSettingsComponent, WidgetConfigComponent, + WidgetPreviewComponent, EntityFilterViewComponent, EntityFilterComponent, EntityAliasSelectComponent, DataKeysComponent, DataKeyConfigComponent, DataKeyConfigDialogComponent, - LegendConfigComponent, ManageWidgetActionsComponent, WidgetActionDialogComponent, CustomActionPrettyResourcesTabsComponent, @@ -371,16 +369,15 @@ import { DeviceInfoFilterComponent } from '@home/components/device/device-info-f DashboardComponent, WidgetContainerComponent, WidgetComponent, - LegendComponent, WidgetSettingsComponent, WidgetConfigComponent, + WidgetPreviewComponent, EntityFilterViewComponent, EntityFilterComponent, EntityAliasSelectComponent, DataKeysComponent, DataKeyConfigComponent, DataKeyConfigDialogComponent, - LegendConfigComponent, ManageWidgetActionsComponent, WidgetActionDialogComponent, CustomActionPrettyResourcesTabsComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.component.html new file mode 100644 index 0000000000..336e137ad6 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.component.html @@ -0,0 +1,32 @@ + +
+ + +
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.component.ts new file mode 100644 index 0000000000..9272295a27 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.component.ts @@ -0,0 +1,151 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; +import { WidgetContext } from '@home/models/widget-component.models'; +import { ChartType, TbFlotSettings } from '@home/components/widget/lib/flot-widget.models'; +import { TbFlot } from '@home/components/widget/lib/flot-widget'; +import { + defaultLegendConfig, + LegendConfig, + LegendData, + LegendPosition, + widgetType +} from '@shared/models/widget.models'; +import { isDefinedAndNotNull } from '@core/utils'; + +@Component({ + selector: 'tb-flot-widget', + templateUrl: './flot-widget.component.html', + styleUrls: [] +}) +export class FlotWidgetComponent implements OnInit { + + @ViewChild('flotElement', {static: true}) flotElement: ElementRef; + + @Input() + ctx: WidgetContext; + + @Input() + chartType: ChartType; + + displayLegend: boolean; + legendConfig: LegendConfig; + legendData: LegendData; + isLegendFirst: boolean; + legendContainerLayoutType: string; + legendStyle: {[klass: string]: any}; + + public settings: TbFlotSettings; + private flot: TbFlot; + + constructor() { + } + + ngOnInit(): void { + this.ctx.$scope.flotWidget = this; + this.settings = this.ctx.settings; + this.chartType = this.chartType || 'line'; + this.configureLegend(); + this.flot = new TbFlot(this.ctx, this.chartType, $(this.flotElement.nativeElement)); + } + + private configureLegend(): void { + + this.displayLegend = isDefinedAndNotNull(this.settings.showLegend) ? this.settings.showLegend + : false; + + this.legendContainerLayoutType = 'column'; + + if (this.displayLegend) { + this.legendConfig = this.settings.legendConfig || defaultLegendConfig(widgetType.timeseries); + if (this.ctx.defaultSubscription) { + this.legendData = this.ctx.defaultSubscription.legendData; + } else { + this.legendData = { + keys: [], + data: [] + }; + } + if (this.legendConfig.position === LegendPosition.top || + this.legendConfig.position === LegendPosition.bottom) { + this.legendContainerLayoutType = 'column'; + this.isLegendFirst = this.legendConfig.position === LegendPosition.top; + } else { + this.legendContainerLayoutType = 'row'; + this.isLegendFirst = this.legendConfig.position === LegendPosition.left; + } + switch (this.legendConfig.position) { + case LegendPosition.top: + this.legendStyle = { + paddingBottom: '8px', + maxHeight: '50%', + overflowY: 'auto' + }; + break; + case LegendPosition.bottom: + this.legendStyle = { + paddingTop: '8px', + maxHeight: '50%', + overflowY: 'auto' + }; + break; + case LegendPosition.left: + this.legendStyle = { + paddingRight: '0px', + maxWidth: '50%', + overflowY: 'auto' + }; + break; + case LegendPosition.right: + this.legendStyle = { + paddingLeft: '0px', + maxWidth: '50%', + overflowY: 'auto' + }; + break; + } + } + } + + public onLegendKeyHiddenChange(index: number) { + for (const id of Object.keys(this.ctx.subscriptions)) { + const subscription = this.ctx.subscriptions[id]; + subscription.updateDataVisibility(index); + } + } + + public onDataUpdated() { + this.flot.update(); + } + + public onLatestDataUpdated() { + this.flot.latestDataUpdate(); + } + + public onResize() { + this.flot.resize(); + } + + public onEditModeChanged() { + this.flot.checkMouseEvents(); + } + + public onDestroy() { + this.flot.destroy(); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts index 6e9e7f85fa..2cc6b40300 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts @@ -17,13 +17,21 @@ // eslint-disable-next-line @typescript-eslint/triple-slash-reference /// -import { DataKey, Datasource, DatasourceData, FormattedData, JsonSettingsSchema } from '@shared/models/widget.models'; +import { + DataKey, + Datasource, + DatasourceData, + FormattedData, + JsonSettingsSchema, + LegendConfig +} from '@shared/models/widget.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { ComparisonDuration } from '@shared/models/time/time.models'; export declare type ChartType = 'line' | 'pie' | 'bar' | 'state' | 'graph'; -export declare type TbFlotSettings = TbFlotBaseSettings & TbFlotGraphSettings & TbFlotBarSettings & TbFlotPieSettings; +export declare type TbFlotSettings = TbFlotBaseSettings & TbFlotLegendSettings & + TbFlotGraphSettings & TbFlotBarSettings & TbFlotPieSettings; export declare type TooltipValueFormatFunction = (value: any, latestData: FormattedData) => string; @@ -140,6 +148,11 @@ export interface TbFlotBaseSettings { yaxis: TbFlotYAxisSettings; } +export interface TbFlotLegendSettings { + showLegend?: boolean; + legendConfig?: LegendConfig; +} + export interface TbFlotComparisonSettings { comparisonEnabled: boolean; timeForComparison: ComparisonDuration; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts index 08a8c92472..c347fa52fc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts @@ -127,7 +127,7 @@ export class TbFlot { private pieAnimationLastTime: number; private pieAnimationCaf: CancelAnimationFrame; - constructor(private ctx: WidgetContext, private readonly chartType: ChartType) { + constructor(private ctx: WidgetContext, private readonly chartType: ChartType, private $flotElement?: JQuery) { this.chartType = this.chartType || 'line'; this.settings = ctx.settings as TbFlotSettings; this.utils = this.ctx.$injector.get(UtilsService); @@ -334,7 +334,7 @@ export class TbFlot { } if (this.ctx.defaultSubscription) { - this.init(this.ctx.$container, this.ctx.defaultSubscription); + this.init(this.$flotElement || this.ctx.$container, this.ctx.defaultSubscription); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/home-page-widgets.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/home-page-widgets.module.ts index 84aeef4118..1b69de8c45 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/home-page-widgets.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/home-page-widgets.module.ts @@ -28,7 +28,6 @@ import { GettingStartedWidgetComponent } from '@home/components/widget/lib/home- import { GettingStartedCompletedDialogComponent } from '@home/components/widget/lib/home-page/getting-started-completed-dialog.component'; -import { ToggleHeaderComponent } from '@home/components/widget/lib/home-page/toggle-header.component'; import { UsageInfoWidgetComponent } from '@home/components/widget/lib/home-page/usage-info-widget.component'; import { QuickLinksWidgetComponent } from '@home/components/widget/lib/home-page/quick-links-widget.component'; import { QuickLinkComponent } from '@home/components/widget/lib/home-page/quick-link.component'; @@ -49,7 +48,6 @@ import { EditLinksDialogComponent, GettingStartedWidgetComponent, GettingStartedCompletedDialogComponent, - ToggleHeaderComponent, UsageInfoWidgetComponent, QuickLinksWidgetComponent, QuickLinkComponent, @@ -70,7 +68,6 @@ import { EditLinksDialogComponent, GettingStartedWidgetComponent, GettingStartedCompletedDialogComponent, - ToggleHeaderComponent, UsageInfoWidgetComponent, QuickLinksWidgetComponent, QuickLinkComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/legend.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/legend.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/legend.component.html rename to ui-ngx/src/app/modules/home/components/widget/lib/legend.component.html diff --git a/ui-ngx/src/app/modules/home/components/widget/legend.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/legend.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/legend.component.scss rename to ui-ngx/src/app/modules/home/components/widget/lib/legend.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/legend.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/legend.component.ts similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/legend.component.ts rename to ui-ngx/src/app/modules/home/components/widget/lib/legend.component.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html index 4c83594e44..284df1e09b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html @@ -68,6 +68,25 @@ +
+ widget-config.legend + + + + + {{ 'widget-config.display-legend' | translate }} + + + + widget-config.advanced-settings + + + + + + +
widgets.chart.tooltip-settings @@ -290,7 +309,7 @@
widgets.chart.custom-legend-settings - + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts index e243232437..98c4acd62b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts @@ -40,8 +40,9 @@ import { labelDataKeyValidator } from '@home/components/widget/lib/settings/chart/label-data-key.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { defaultLegendConfig, widgetType } from '@shared/models/widget.models'; -export function flotDefaultSettings(chartType: ChartType): Partial { +export const flotDefaultSettings = (chartType: ChartType): Partial => { const settings: Partial = { stack: false, fontColor: '#545454', @@ -95,9 +96,11 @@ export function flotDefaultSettings(chartType: ChartType): Partial { + this.updateValidators(true); + }); this.flotSettingsFormGroup.get('comparisonEnabled').valueChanges.subscribe(() => { this.updateValidators(true); }); @@ -350,9 +361,15 @@ export class FlotWidgetSettingsComponent extends PageComponent implements OnInit this.flotSettingsFormGroup.get('yaxis.ticksFormatter').updateValueAndValidity({emitEvent: false}); if (this.chartType === 'graph' || this.chartType === 'bar') { + const showLegend: boolean = this.flotSettingsFormGroup.get('showLegend').value; const comparisonEnabled: boolean = this.flotSettingsFormGroup.get('comparisonEnabled').value; const timeForComparison: ComparisonDuration = this.flotSettingsFormGroup.get('timeForComparison').value; const customLegendEnabled: boolean = this.flotSettingsFormGroup.get('customLegendEnabled').value; + if (showLegend) { + this.flotSettingsFormGroup.get('legendConfig').enable({emitEvent}); + } else { + this.flotSettingsFormGroup.get('legendConfig').disable({emitEvent}); + } if (comparisonEnabled) { this.flotSettingsFormGroup.get('timeForComparison').enable({emitEvent: false}); if (timeForComparison === 'customInterval') { @@ -370,6 +387,7 @@ export class FlotWidgetSettingsComponent extends PageComponent implements OnInit this.flotSettingsFormGroup.get('dataKeysListForLabels').disable({emitEvent}); } + this.flotSettingsFormGroup.get('legendConfig').updateValueAndValidity({emitEvent: false}); this.flotSettingsFormGroup.get('timeForComparison').updateValueAndValidity({emitEvent: false}); this.flotSettingsFormGroup.get('comparisonCustomIntervalValue').updateValueAndValidity({emitEvent: false}); this.flotSettingsFormGroup.get('dataKeysListForLabels').updateValueAndValidity({emitEvent: false}); diff --git a/ui-ngx/src/app/modules/home/components/widget/legend-config.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/legend-config.component.html rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.html diff --git a/ui-ngx/src/app/modules/home/components/widget/legend-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.ts similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/legend-config.component.ts rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts index 11aaf06a93..2dae32a922 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts @@ -265,6 +265,7 @@ import { import { QuickLinksWidgetSettingsComponent } from '@home/components/widget/lib/settings/home-page/quick-links-widget-settings.component'; +import { LegendConfigComponent } from '@home/components/widget/lib/settings/common/legend-config.component'; @NgModule({ declarations: [ @@ -290,6 +291,7 @@ import { AnalogueCompassWidgetSettingsComponent, DigitalGaugeWidgetSettingsComponent, ValueSourceComponent, + LegendConfigComponent, FixedColorLevelComponent, TickValueComponent, FlotWidgetSettingsComponent, @@ -395,6 +397,7 @@ import { AnalogueCompassWidgetSettingsComponent, DigitalGaugeWidgetSettingsComponent, ValueSourceComponent, + LegendConfigComponent, FixedColorLevelComponent, TickValueComponent, FlotWidgetSettingsComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts index 4f0454bb1c..5368ed2e71 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts @@ -41,6 +41,8 @@ import { MarkdownWidgetComponent } from '@home/components/widget/lib/markdown-wi import { SelectEntityDialogComponent } from '@home/components/widget/lib/maps/dialogs/select-entity-dialog.component'; import { HomePageWidgetsModule } from '@home/components/widget/lib/home-page/home-page-widgets.module'; import { WIDGET_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens'; +import { FlotWidgetComponent } from '@home/components/widget/lib/flot-widget.component'; +import { LegendComponent } from '@home/components/widget/lib/legend.component'; @NgModule({ declarations: @@ -62,7 +64,9 @@ import { WIDGET_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens'; NavigationCardWidgetComponent, QrCodeWidgetComponent, MarkdownWidgetComponent, - SelectEntityDialogComponent + SelectEntityDialogComponent, + LegendComponent, + FlotWidgetComponent ], imports: [ CommonModule, @@ -88,7 +92,9 @@ import { WIDGET_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens'; NavigationCardsWidgetComponent, NavigationCardWidgetComponent, QrCodeWidgetComponent, - MarkdownWidgetComponent + MarkdownWidgetComponent, + LegendComponent, + FlotWidgetComponent ], providers: [ {provide: WIDGET_COMPONENTS_MODULE_TOKEN, useValue: WidgetComponentsModule } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html index 7d39455f36..f2e2a0e8ba 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html @@ -15,9 +15,15 @@ limitations under the License. --> - - -
+
+
+ + + +
+
+
@@ -55,7 +61,7 @@
{{ 'widget-config.maximum-datasources' | translate:{count: modelValue?.typeParameters.maxDatasources} }}
- report_gmailerrorred @@ -64,7 +70,7 @@ {{ 'widget-config.timeseries-key-error' | translate }} -
+
datasource.add-datasource-prompt
@@ -86,7 +92,7 @@ (cdkDropListDropped)="onDatasourceDrop($event)" [cdkDropListDisabled]="disabled" formArrayName="datasources"> -
@@ -205,7 +211,7 @@ type="button" mat-raised-button color="primary" [fxShow]="modelValue?.typeParameters && - (modelValue?.typeParameters.maxDatasources === -1 || datasourcesFormArray().controls.length < modelValue?.typeParameters.maxDatasources)" + (modelValue?.typeParameters.maxDatasources === -1 || datasourcesFormArray()?.controls?.length < modelValue?.typeParameters.maxDatasources)" (click)="addDatasource()" matTooltip="{{ 'widget-config.add-datasource' | translate }}" matTooltipPosition="above"> @@ -223,11 +229,11 @@
+ [tbRequired]="!widgetEditMode" + [aliasController]="aliasController" + [allowedEntityTypes]="[entityTypes.DEVICE]" + [callbacks]="widgetConfigCallbacks" + formControlName="targetDeviceAliasId">
@@ -312,183 +318,148 @@
- - -
-
-
- widget-config.title - - {{ 'widget-config.display-title' | translate }} +
+ + +
+
+
+ widget-config.title + + {{ 'widget-config.display-title' | translate }} + +
+ + widget-config.title + + + + widget-config.title-tooltip + + +
+
+ widget-config.title-icon + + {{ 'widget-config.display-icon' | translate }}
+ + + + - widget-config.title - - - - widget-config.title-tooltip - + widget-config.icon-size +
-
- widget-config.title-icon - - {{ 'widget-config.display-icon' | translate }} - -
- - - - - - widget-config.icon-size - - -
-
- - - - widget-config.advanced-settings - - - - - -
-
- widget-config.widget-style -
-
- - - - -
-
- - widget-config.padding - - - - widget-config.margin - - -
+ + + + widget-config.advanced-settings + + + + + + +
+
+ widget-config.widget-style +
+
+ + + +
- - {{ 'widget-config.drop-shadow' | translate }} - - - {{ 'widget-config.enable-fullscreen' | translate }} - - - - - widget-config.advanced-settings - - - - - - - -
-
- widget-config.legend - - - - - {{ 'widget-config.display-legend' | translate }} - - - - widget-config.advanced-settings - - - - - - -
-
- widget-config.mobile-mode-settings - - - - - {{ 'widget-config.mobile-hide' | translate }} - - - {{ 'widget-config.desktop-hide' | translate }} - - - - widget-config.advanced-settings - - - -
- - widget-config.order - - - - widget-config.height - - -
-
-
-
-
+
+ + widget-config.padding + + + + widget-config.margin + + +
+
+ + {{ 'widget-config.drop-shadow' | translate }} + + + {{ 'widget-config.enable-fullscreen' | translate }} + + + + + widget-config.advanced-settings + + + + + + + +
- - -
- - +
+ +
- - - - - - +
+ + {{ 'widget-config.mobile-hide' | translate }} + + + {{ 'widget-config.desktop-hide' | translate }} + +
+ + widget-config.order + + + + widget-config.height + + +
+
+
+ + diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss index 2ae2eaa211..e3926c8eea 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss @@ -16,6 +16,24 @@ @import '../../../../../scss/constants'; .tb-widget-config { + display: flex; + flex-direction: column; + gap: 16px; + .tb-widget-config-header { + padding: 24px 24px 8px; + height: 56px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + } + .tb-widget-config-content { + flex: 1; + overflow: auto; + & > div { + padding: 16px; + } + } .tb-panel-hint { font-size: 12px; color: #808080; @@ -120,6 +138,11 @@ :host ::ng-deep { .tb-widget-config { + .tb-widget-config-header { + .mat-button-toggle-appearance-standard .mat-button-toggle-label-content { + padding: 0 20px; + } + } tb-alarm-filter-config { .mdc-button { width: 100%; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index 1514c1b929..634b893526 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -25,7 +25,6 @@ import { datasourcesHasOnlyComparisonAggregation, DatasourceType, datasourceTypeTranslationMap, - defaultLegendConfig, GroupInfo, JsonSchema, JsonSettingsSchema, @@ -68,6 +67,7 @@ import { entityFields } from '@shared/models/entity.models'; import { Filter } from '@shared/models/query/query.models'; import { FilterDialogComponent, FilterDialogData } from '@home/components/filter/filter-dialog.component'; import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { ToggleHeaderOption } from '@shared/components/toggle-header.component'; const emptySettingsSchema: JsonSchema = { type: 'object', @@ -95,7 +95,7 @@ const defaultSettingsForm = [ } ] }) -export class WidgetConfigComponent extends PageComponent implements OnInit, ControlValueAccessor, Validator { +export class WidgetConfigComponent extends PageComponent implements OnInit, OnDestroy, ControlValueAccessor, Validator { widgetTypes = widgetType; @@ -134,14 +134,13 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont widgetEditMode = this.utils.widgetEditMode; - selectedTab: number; - modelValue: WidgetConfigComponentData; - showLegendFieldset = true; - private propagateChange = null; + headerOptions: ToggleHeaderOption[] = []; + selectedOption: string; + public dataSettings: UntypedFormGroup; public targetDeviceSettings: UntypedFormGroup; public alarmSourceSettings: UntypedFormGroup; @@ -196,9 +195,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont pageSize: [1024, [Validators.min(1), Validators.pattern(/^\d*$/)]], units: [null, []], decimals: [null, [Validators.min(0), Validators.max(15), Validators.pattern(/^\d*$/)]], - noDataDisplayMessage: [null, []], - showLegend: [null, []], - legendConfig: [null, []] + noDataDisplayMessage: [null, []] }); this.widgetSettings.get('showTitle').valueChanges.subscribe((value: boolean) => { if (value) { @@ -224,13 +221,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont this.widgetSettings.get('iconSize').disable({emitEvent: false}); } }); - this.widgetSettings.get('showLegend').valueChanges.subscribe((value: boolean) => { - if (value) { - this.widgetSettings.get('legendConfig').enable({emitEvent: false}); - } else { - this.widgetSettings.get('legendConfig').disable({emitEvent: false}); - } - }); this.layoutSettings = this.fb.group({ mobileOrder: [null, [Validators.pattern(/^-?[0-9]+$/)]], mobileHeight: [null, [Validators.min(1), Validators.pattern(/^\d*$/)]], @@ -370,15 +360,49 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont this.modelValue = value; this.removeChangeSubscriptions(); if (this.modelValue) { + this.headerOptions.length = 0; + if (this.modelValue.widgetType !== widgetType.static) { + this.headerOptions.push( + { + name: this.translate.instant('widget-config.data'), + value: 'data' + } + ); + } + if (this.displayAdvanced()) { + this.headerOptions.push( + { + name: this.translate.instant('widget-config.appearance'), + value: 'appearance' + } + ); + } + this.headerOptions.push( + { + name: this.translate.instant('widget-config.widget-card'), + value: 'card' + } + ); + this.headerOptions.push( + { + name: this.translate.instant('widget-config.actions'), + value: 'actions' + } + ); + this.headerOptions.push( + { + name: this.translate.instant('widget-config.mobile'), + value: 'mobile' + } + ); + this.selectedOption = this.headerOptions[0].value; if (this.widgetType !== this.modelValue.widgetType) { this.widgetType = this.modelValue.widgetType; - this.showLegendFieldset = (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.latest); this.buildForms(); } const config = this.modelValue.config; const layout = this.modelValue.layout; if (config) { - this.selectedTab = 0; const displayWidgetTitle = isDefined(config.showTitle) ? config.showTitle : false; this.widgetSettings.patchValue({ title: config.title, @@ -403,10 +427,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont pageSize: isDefined(config.pageSize) ? config.pageSize : 1024, units: config.units, decimals: config.decimals, - noDataDisplayMessage: isDefined(config.noDataDisplayMessage) ? config.noDataDisplayMessage : '', - showLegend: isDefined(config.showLegend) ? config.showLegend : - this.widgetType === widgetType.timeseries, - legendConfig: config.legendConfig || defaultLegendConfig(this.widgetType) + noDataDisplayMessage: isDefined(config.noDataDisplayMessage) ? config.noDataDisplayMessage : '' }, {emitEvent: false} ); @@ -430,12 +451,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont this.widgetSettings.get('iconColor').disable({emitEvent: false}); this.widgetSettings.get('iconSize').disable({emitEvent: false}); } - const showLegend: boolean = this.widgetSettings.get('showLegend').value; - if (showLegend) { - this.widgetSettings.get('legendConfig').enable({emitEvent: false}); - } else { - this.widgetSettings.get('legendConfig').disable({emitEvent: false}); - } const actionsData: WidgetActionsData = { actionsMap: config.actions || {}, actionSources: this.modelValue.actionSources || {} @@ -812,15 +827,13 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, Cont private fetchEntityKeys(entityAliasId: string, dataKeyTypes: Array): Observable> { return this.aliasController.getAliasInfo(entityAliasId).pipe( - mergeMap((aliasInfo) => { - return this.entityService.getEntityKeysByEntityFilter( + mergeMap((aliasInfo) => this.entityService.getEntityKeysByEntityFilter( aliasInfo.entityFilter, dataKeyTypes, {ignoreLoading: true, ignoreErrors: true} ).pipe( catchError(() => of([])) - ); - }), + )), catchError(() => of([] as Array)) ); } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html new file mode 100644 index 0000000000..7948cb19d4 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html @@ -0,0 +1,32 @@ + + + +widget-config.preview +
+ +
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.scss b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.scss new file mode 100644 index 0000000000..73636f346b --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.scss @@ -0,0 +1,49 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host { + z-index: 10; + background: #F3F6FA; + .tb-preview-dashboard { + position: absolute; + top: 15%; + bottom: 15%; + left: 0; + right: 0; + } + .tb-preview-title { + position: absolute; + top: 16px; + left: 16px; + font-weight: 500; + font-size: 13px; + line-height: 16px; + letter-spacing: normal; + color: rgba(0, 0, 0, 0.38); + } + .tb-preview-panel { + position: absolute; + top: 16px; + right: 24px; + } +} + +:host ::ng-deep { + tb-dashboard.tb-preview-dashboard { + .tb-dashboard-content { + background-color: transparent !important; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts new file mode 100644 index 0000000000..3d82caa9a7 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts @@ -0,0 +1,64 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, Validator } from '@angular/forms'; +import { PageComponent } from '@shared/components/page.component'; +import { IAliasController, IStateController } from '@core/api/widget-api.models'; +import { Widget, WidgetConfig } from '@shared/models/widget.models'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { deepClone } from '@core/utils'; + +@Component({ + selector: 'tb-widget-preview', + templateUrl: './widget-preview.component.html', + styleUrls: ['./widget-preview.component.scss'] +}) +export class WidgetPreviewComponent extends PageComponent implements OnInit { + + @Input() + aliasController: IAliasController; + + @Input() + stateController: IStateController; + + @Input() + widget: Widget; + + @Input() + widgetConfig: WidgetConfig; + + widgets: Widget[]; + + constructor(protected store: Store) { + super(store); + } + + ngOnInit(): void { + const sizeX = this.widget.sizeX * 2; + const sizeY = this.widget.sizeY * 2; + const col = Math.floor(Math.max(0, (20 - sizeX) / 2)); + const widget = deepClone(this.widget); + widget.sizeX = sizeX; + widget.sizeY = sizeY; + widget.row = 0; + widget.col = col; + widget.config = this.widgetConfig; + this.widgets = [widget]; + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.html b/ui-ngx/src/app/modules/home/components/widget/widget.component.html index 0f8f6a9997..76c800f524 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.html @@ -15,23 +15,11 @@ limitations under the License. --> -
- -
- -
Widget Error: {{ widgetErrorData.name + ": " + widgetErrorData.message}} @@ -42,5 +30,5 @@ class="tb-absolute-fill">{{ noDataDisplayMessageText }}
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index 5a3b55bf2d..7e1dfdc617 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -39,10 +39,6 @@ import { } from '@angular/core'; import { DashboardWidget } from '@home/models/dashboard-component.models'; import { - defaultLegendConfig, - LegendConfig, - LegendData, - LegendPosition, Widget, WidgetActionDescriptor, widgetActionSources, @@ -152,13 +148,6 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI displayNoData = false; noDataDisplayMessageText: string; - displayLegend: boolean; - legendConfig: LegendConfig; - legendData: LegendData; - isLegendFirst: boolean; - legendContainerLayoutType: string; - legendStyle: {[klass: string]: any}; - dynamicWidgetComponentRef: ComponentRef; dynamicWidgetComponent: IDynamicWidgetComponent; @@ -220,57 +209,6 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.widget = this.dashboardWidget.widget; - this.displayLegend = isDefined(this.widget.config.showLegend) ? this.widget.config.showLegend - : this.widget.type === widgetType.timeseries; - - this.legendContainerLayoutType = 'column'; - - if (this.displayLegend) { - this.legendConfig = this.widget.config.legendConfig || defaultLegendConfig(this.widget.type); - this.legendData = { - keys: [], - data: [] - }; - if (this.legendConfig.position === LegendPosition.top || - this.legendConfig.position === LegendPosition.bottom) { - this.legendContainerLayoutType = 'column'; - this.isLegendFirst = this.legendConfig.position === LegendPosition.top; - } else { - this.legendContainerLayoutType = 'row'; - this.isLegendFirst = this.legendConfig.position === LegendPosition.left; - } - switch (this.legendConfig.position) { - case LegendPosition.top: - this.legendStyle = { - paddingBottom: '8px', - maxHeight: '50%', - overflowY: 'auto' - }; - break; - case LegendPosition.bottom: - this.legendStyle = { - paddingTop: '8px', - maxHeight: '50%', - overflowY: 'auto' - }; - break; - case LegendPosition.left: - this.legendStyle = { - paddingRight: '0px', - maxWidth: '50%', - overflowY: 'auto' - }; - break; - case LegendPosition.right: - this.legendStyle = { - paddingLeft: '0px', - maxWidth: '50%', - overflowY: 'auto' - }; - break; - } - } - const actionDescriptorsBySourceId: {[actionSourceId: string]: Array} = {}; if (this.widget.config.actions) { for (const actionSourceId of Object.keys(this.widget.config.actions)) { @@ -463,13 +401,6 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI } } - public onLegendKeyHiddenChange(index: number) { - for (const id of Object.keys(this.widgetContext.subscriptions)) { - const subscription = this.widgetContext.subscriptions[id]; - subscription.updateDataVisibility(index); - } - } - private loadFromWidgetInfo() { this.widgetContext.widgetNamespace = `widget-type-${(this.widget.isSystemType ? 'sys-' : '')}${this.widget.bundleAlias}-${this.widget.typeAlias}`; @@ -872,9 +803,6 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI } this.createSubscription(options, subscribe).subscribe( (subscription) => { - if (useDefaultComponents) { - this.defaultSubscriptionOptions(subscription, options); - } createSubscriptionSubject.next(subscription); createSubscriptionSubject.complete(); }, @@ -892,8 +820,8 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI ? this.widget.config.displayTimewindow : !options.useDashboardTimewindow; options.timeWindowConfig = options.useDashboardTimewindow ? this.widgetContext.dashboardTimewindow : this.widget.config.timewindow; options.legendConfig = null; - if (this.displayLegend) { - options.legendConfig = this.legendConfig; + if (this.widget.config.settings.showLegend === true) { + options.legendConfig = this.widget.config.settings.legendConfig; } options.decimals = this.widgetContext.decimals; options.units = this.widgetContext.units; @@ -962,13 +890,6 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI }); } }; - - } - - private defaultSubscriptionOptions(subscription: IWidgetSubscription, options: WidgetSubscriptionOptions) { - if (this.displayLegend) { - this.legendData = subscription.legendData; - } } private createDefaultSubscription(): Observable { @@ -999,7 +920,6 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.createSubscription(options).subscribe( (subscription) => { - this.defaultSubscriptionOptions(subscription, options); // backward compatibility this.widgetContext.datasources = subscription.datasources; @@ -1479,7 +1399,8 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI } } - private loadCustomActionResources(actionNamespace: string, customCss: string, customResources: Array, actionDescriptor: WidgetActionDescriptor): Observable { + private loadCustomActionResources(actionNamespace: string, customCss: string, customResources: Array, + actionDescriptor: WidgetActionDescriptor): Observable { const resourceTasks: Observable[] = []; const modulesTasks: Observable[] = []; diff --git a/ui-ngx/src/app/shared/components/public-api.ts b/ui-ngx/src/app/shared/components/public-api.ts index 2443bc6d43..1dd31182f1 100644 --- a/ui-ngx/src/app/shared/components/public-api.ts +++ b/ui-ngx/src/app/shared/components/public-api.ts @@ -22,3 +22,4 @@ export * from './js-func.component'; export * from './script-lang.component'; export * from './slack-conversation-autocomplete.component'; export * from './notification/template-autocomplete.component'; +export * from './toggle-header.component'; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.html b/ui-ngx/src/app/shared/components/toggle-header.component.html similarity index 87% rename from ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.html rename to ui-ngx/src/app/shared/components/toggle-header.component.html index ed39fca25d..3cc0f8beaf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.html +++ b/ui-ngx/src/app/shared/components/toggle-header.component.html @@ -15,7 +15,8 @@ limitations under the License. --> - {{ option.name }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.scss b/ui-ngx/src/app/shared/components/toggle-header.component.scss similarity index 91% rename from ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.scss rename to ui-ngx/src/app/shared/components/toggle-header.component.scss index 1e901b056a..683d364058 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.scss +++ b/ui-ngx/src/app/shared/components/toggle-header.component.scss @@ -14,7 +14,7 @@ * limitations under the License. */ -@import "../../../../../../../scss/constants"; +@import "../../../scss/constants"; :host ::ng-deep { .mat-button-toggle-group.mat-button-toggle-group-appearance-standard.tb-toggle-header { @@ -58,9 +58,19 @@ } } } + &.tb-fill { + .mat-button-toggle.mat-button-toggle-appearance-standard { + &.mat-button-toggle-checked { + .mat-button-toggle-button { + background: #305680; + color: #FFFFFF; + } + } + } + } } @media #{$mat-md-lg} { - .mat-button-toggle-group.mat-button-toggle-group-appearance-standard.tb-toggle-header { + .mat-button-toggle-group.mat-button-toggle-group-appearance-standard.tb-toggle-header:not(.tb-ignore-md-lg) { height: 24px; .mat-button-toggle.mat-button-toggle-appearance-standard { .mat-button-toggle-button { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.ts b/ui-ngx/src/app/shared/components/toggle-header.component.ts similarity index 93% rename from ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.ts rename to ui-ngx/src/app/shared/components/toggle-header.component.ts index b8fd5c63bb..7a66ac6c16 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/toggle-header.component.ts +++ b/ui-ngx/src/app/shared/components/toggle-header.component.ts @@ -44,6 +44,8 @@ export interface ToggleHeaderOption { value: any; } +export type ToggleHeaderAppearance = 'fill' | 'stroked'; + @Component({ selector: 'tb-toggle-header', templateUrl: './toggle-header.component.html', @@ -67,6 +69,13 @@ export class ToggleHeaderComponent extends PageComponent implements OnInit { @coerceBoolean() useSelectOnMdLg = true; + @Input() + @coerceBoolean() + ignoreMdLgSize = false; + + @Input() + appearance: ToggleHeaderAppearance = 'stroked'; + isMdLg: boolean; private observeBreakpointSubscription: Subscription; diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index b20565a50b..77d2acf3e2 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -252,18 +252,16 @@ export interface LegendConfig { showLatest: boolean; } -export function defaultLegendConfig(wType: widgetType): LegendConfig { - return { - direction: LegendDirection.column, - position: LegendPosition.bottom, - sortDataKeys: false, - showMin: false, - showMax: false, - showAvg: wType === widgetType.timeseries, - showTotal: false, - showLatest: false - }; -} +export const defaultLegendConfig = (wType: widgetType): LegendConfig => ({ + direction: LegendDirection.column, + position: LegendPosition.bottom, + sortDataKeys: false, + showMin: false, + showMax: false, + showAvg: wType === widgetType.timeseries, + showTotal: false, + showLatest: false +}); export enum ComparisonResultType { PREVIOUS_VALUE = 'PREVIOUS_VALUE', @@ -363,7 +361,7 @@ export interface Datasource { [key: string]: any; } -export function datasourcesHasAggregation(datasources?: Array): boolean { +export const datasourcesHasAggregation = (datasources?: Array): boolean => { if (datasources) { const foundDatasource = datasources.find(datasource => { const found = datasource.dataKeys && datasource.dataKeys.find(key => key.type === DataKeyType.timeseries && @@ -375,9 +373,9 @@ export function datasourcesHasAggregation(datasources?: Array): bool } } return false; -} +}; -export function datasourcesHasOnlyComparisonAggregation(datasources?: Array): boolean { +export const datasourcesHasOnlyComparisonAggregation = (datasources?: Array): boolean => { if (!datasourcesHasAggregation(datasources)) { return false; } @@ -392,7 +390,7 @@ export function datasourcesHasOnlyComparisonAggregation(datasources?: Array { if (settings) { const keys = Object.keys(settings); for (const key of keys) { @@ -711,7 +707,7 @@ function removeEmptyWidgetSettings(settings: WidgetSettings): WidgetSettings { } } return settings; -} +}; @Directive() // eslint-disable-next-line @angular-eslint/directive-class-suffix diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts index 9bd9006399..0c6c0ac03f 100644 --- a/ui-ngx/src/app/shared/shared.module.ts +++ b/ui-ngx/src/app/shared/shared.module.ts @@ -189,6 +189,7 @@ import { } from '@shared/layout/layout.directives'; import { ColorPickerComponent } from '@shared/components/color-picker/color-picker.component'; import { ShortNumberPipe } from '@shared/pipe/short-number.pipe'; +import { ToggleHeaderComponent } from '@shared/components/toggle-header.component'; export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) { return markedOptionsService; @@ -356,7 +357,8 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) GtMdLgLayoutAlignDirective, GtMdLgLayoutGapDirective, GtMdLgShowHideDirective, - ColorPickerComponent + ColorPickerComponent, + ToggleHeaderComponent ], imports: [ CommonModule, @@ -580,7 +582,8 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) GtMdLgLayoutAlignDirective, GtMdLgLayoutGapDirective, GtMdLgShowHideDirective, - ColorPickerComponent + ColorPickerComponent, + ToggleHeaderComponent ] }) export class SharedModule { } 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 ee081d9727..432c03f4b3 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -35,6 +35,7 @@ "edit-mode": "Edit mode", "enter-edit-mode": "Enter edit mode", "decline-changes": "Decline changes", + "decline": "Decline", "close": "Close", "back": "Back", "run": "Run", @@ -4091,6 +4092,9 @@ "data": "Data", "settings": "Settings", "advanced": "Advanced", + "appearance": "Appearance", + "widget-card": "Widget card", + "mobile": "Mobile", "title": "Title", "title-tooltip": "Title Tooltip", "general-settings": "General settings", @@ -4151,7 +4155,8 @@ "data-settings": "Data settings", "no-data-display-message": "\"No data to display\" alternative message", "data-page-size": "Maximum entities per datasource", - "settings-component-not-found": "Settings form component not found for selector '{{selector}}'" + "settings-component-not-found": "Settings form component not found for selector '{{selector}}'", + "preview": "Preview" }, "widget-type": { "import": "Import widget type", From b083ab98e043321fa598de7f9188600c15e1cb80 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 17 May 2023 15:10:57 +0300 Subject: [PATCH 057/207] updated GET /resources api to filter resources by type --- .../controller/ControllerConstants.java | 3 + .../controller/TbResourceController.java | 18 ++- .../resource/DefaultTbResourceService.java | 10 ++ .../service/resource/TbResourceService.java | 4 + .../controller/TbResourceControllerTest.java | 119 ++++++++++++++++++ .../server/dao/resource/ResourceService.java | 4 + .../server/common/data/ResourceType.java | 2 +- .../dao/resource/BaseResourceService.java | 14 +++ .../dao/resource/TbResourceInfoDao.java | 4 + .../sql/resource/JpaTbResourceInfoDao.java | 21 ++++ .../resource/TbResourceInfoRepository.java | 25 ++++ 11 files changed, 221 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index f425bde86c..1cb794c2ec 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java @@ -140,6 +140,9 @@ public class ControllerConstants { protected static final String RESOURCE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the resource title."; protected static final String RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, resourceType, tenantId"; + protected static final String RESOURCE_TYPE_PROPERTY_ALLOWABLE_VALUES = "LWM2M_MODEL, JKS, PKCS_12, JS_MODULE"; + protected static final String RESOURCE_TYPE = "A string value representing the resource type."; + protected static final String LWM2M_OBJECT_DESCRIPTION = "LwM2M Object is a object that includes information about the LwM2M model which can be used in transport configuration for the LwM2M device profile. "; protected static final String LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name"; diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index d94dc31fa1..316599a092 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -31,6 +31,8 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.ResourceType; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -57,6 +59,8 @@ import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_ID_ import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_INFO_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TEXT_SEARCH_DESCRIPTION; +import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TYPE; +import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TYPE_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; @@ -153,6 +157,8 @@ public class TbResourceController extends BaseController { @RequestParam int pageSize, @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, + @ApiParam(value = RESOURCE_TYPE, allowableValues = RESOURCE_TYPE_PROPERTY_ALLOWABLE_VALUES) + @RequestParam(required = false) String resourceType, @ApiParam(value = RESOURCE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES) @@ -161,9 +167,17 @@ public class TbResourceController extends BaseController { @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { - return checkNotNull(resourceService.findTenantResourcesByTenantId(getTenantId(), pageLink)); + if (StringUtils.isNotEmpty(resourceType)){ + return checkNotNull(resourceService.findTenantResourcesByType(getTenantId(), ResourceType.valueOf(resourceType), pageLink)); + } else { + return checkNotNull(resourceService.findTenantResourcesByTenantId(getTenantId(), pageLink)); + } } else { - return checkNotNull(resourceService.findAllTenantResourcesByTenantId(getTenantId(), pageLink)); + if (StringUtils.isNotEmpty(resourceType)){ + return checkNotNull(resourceService.findAllTenantResourcesByType(getTenantId(), ResourceType.valueOf(resourceType), pageLink)); + } else { + return checkNotNull(resourceService.findAllTenantResourcesByTenantId(getTenantId(), pageLink)); + } } } diff --git a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java index 5cf051367a..ece58397ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java @@ -85,6 +85,16 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements return resourceService.findTenantResourcesByTenantId(tenantId, pageLink); } + @Override + public PageData findAllTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { + return resourceService.findAllTenantResourcesByType(tenantId, resourceType, pageLink); + } + + @Override + public PageData findTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { + return resourceService.findTenantResourcesByType(tenantId, resourceType, pageLink); + } + @Override public List findLwM2mObject(TenantId tenantId, String sortOrder, String sortProperty, String[] objectIds) { log.trace("Executing findByTenantId [{}]", tenantId); diff --git a/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java index 024d391482..c3b6506abe 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java @@ -39,6 +39,10 @@ public interface TbResourceService extends SimpleTbEntityService { PageData findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); + PageData findAllTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + + PageData findTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + List findLwM2mObject(TenantId tenantId, String sortOrder, String sortProperty, diff --git a/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java index de8f717c0d..dbe0c591e9 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java @@ -47,6 +47,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); private static final String DEFAULT_FILE_NAME = "test.jks"; + private static final String DEFAULT_FILE_NAME_2 = "test2.jks"; private Tenant savedTenant; private User tenantAdmin; @@ -242,6 +243,54 @@ public class TbResourceControllerTest extends AbstractControllerTest { Assert.assertEquals(resources, loadedResources); } + @Test + public void testFindTenantTbResourcesByType() throws Exception { + Mockito.reset(tbClusterService, auditLogService); + + List resources = new ArrayList<>(); + int jksCntEntity = 17; + for (int i = 0; i < jksCntEntity; i++) { + TbResource resource = new TbResource(); + resource.setTitle("JKS Resource" + i); + resource.setResourceType(ResourceType.JKS); + resource.setFileName(i + DEFAULT_FILE_NAME); + resource.setData("Test Data"); + resources.add(new TbResourceInfo(save(resource))); + } + + int lwm2mCntEntity = 19; + for (int i = 0; i < lwm2mCntEntity; i++) { + TbResource resource = new TbResource(); + resource.setTitle("LWM2M Resource" + i); + resource.setResourceType(ResourceType.PKCS_12); + resource.setFileName(i + DEFAULT_FILE_NAME_2); + resource.setData("Test Data"); + save(resource); + } + + List loadedResources = new ArrayList<>(); + PageLink pageLink = new PageLink(5); + PageData pageData; + do { + pageData = doGetTypedWithPageLink("/api/resource?resourceType=" + ResourceType.JKS.name() + "&", + new TypeReference<>() { + }, pageLink); + loadedResources.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + + testNotifyManyEntityManyTimeMsgToEdgeServiceNever(new TbResource(), new TbResource(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ADDED, jksCntEntity + lwm2mCntEntity); + + Collections.sort(resources, idComparator); + Collections.sort(loadedResources, idComparator); + + Assert.assertEquals(resources, loadedResources); + } + @Test public void testFindSystemTbResources() throws Exception { loginSysAdmin(); @@ -300,6 +349,76 @@ public class TbResourceControllerTest extends AbstractControllerTest { Assert.assertTrue(loadedResources.isEmpty()); } + @Test + public void testFindSystemTbResourcesByType() throws Exception { + loginSysAdmin(); + + List resources = new ArrayList<>(); + int jksCntEntity = 17; + for (int i = 0; i < jksCntEntity; i++) { + TbResource resource = new TbResource(); + resource.setTitle("JKS Resource" + i); + resource.setResourceType(ResourceType.JKS); + resource.setFileName(i + DEFAULT_FILE_NAME); + resource.setData("Test Data"); + resources.add(new TbResourceInfo(save(resource))); + } + + int lwm2mCntEntity = 19; + for (int i = 0; i < lwm2mCntEntity; i++) { + TbResource resource = new TbResource(); + resource.setTitle("LWM2M Resource" + i); + resource.setResourceType(ResourceType.PKCS_12); + resource.setFileName(i + DEFAULT_FILE_NAME_2); + resource.setData("Test Data"); + save(resource); + } + + List loadedResources = new ArrayList<>(); + PageLink pageLink = new PageLink(30); + PageData pageData; + do { + pageData = doGetTypedWithPageLink("/api/resource?resourceType=" + ResourceType.JKS + "&", + new TypeReference<>() { + }, pageLink); + loadedResources.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + + Collections.sort(resources, idComparator); + Collections.sort(loadedResources, idComparator); + + Assert.assertEquals(resources, loadedResources); + + Mockito.reset(tbClusterService, auditLogService); + + int cntEntity = resources.size(); + for (TbResourceInfo resource : resources) { + doDelete("/api/resource/" + resource.getId().getId().toString()) + .andExpect(status().isOk()); + } + + testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new TbResource(), new TbResource(), + resources.get(0).getTenantId(), null, null, SYS_ADMIN_EMAIL, + ActionType.DELETED, cntEntity, 1); + + pageLink = new PageLink(27); + loadedResources.clear(); + do { + pageData = doGetTypedWithPageLink("/api/resource?resourceType=" + ResourceType.JKS + "&", + new TypeReference<>() { + }, pageLink); + loadedResources.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + + Assert.assertTrue(loadedResources.isEmpty()); + } + @Test public void testFindSystemAndTenantTbResources() throws Exception { List systemResources = new ArrayList<>(); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 5e05cdddc6..779fbaf275 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -43,6 +43,10 @@ public interface ResourceService extends EntityDaoService { PageData findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); + PageData findAllTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + + PageData findTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + List findTenantResourcesByResourceTypeAndObjectIds(TenantId tenantId, ResourceType lwm2mModel, String[] objectIds); PageData findTenantResourcesByResourceTypeAndPageLink(TenantId tenantId, ResourceType lwm2mModel, PageLink pageLink); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java index 31c87ecfde..a9c34a3903 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java @@ -16,5 +16,5 @@ package org.thingsboard.server.common.data; public enum ResourceType { - LWM2M_MODEL, JKS, PKCS_12 + LWM2M_MODEL, JKS, PKCS_12, JS_MODULE } diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index f5ba4abf2c..3bc02f0a5a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -116,6 +116,20 @@ public class BaseResourceService implements ResourceService { return resourceInfoDao.findTenantResourcesByTenantId(tenantId.getId(), pageLink); } + @Override + public PageData findAllTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { + log.trace("Executing findAllTenantResourcesByType [{}]", tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + return resourceInfoDao.findAllTenantResourcesByType(tenantId.getId(), resourceType.name(), pageLink); + } + + @Override + public PageData findTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { + log.trace("Executing findTenantResourcesByType [{}]", tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + return resourceInfoDao.findTenantResourcesByType(tenantId.getId(), resourceType.name(), pageLink); + } + @Override public List findTenantResourcesByResourceTypeAndObjectIds(TenantId tenantId, ResourceType resourceType, String[] objectIds) { log.trace("Executing findTenantResourcesByResourceTypeAndObjectIds [{}][{}][{}]", tenantId, resourceType, objectIds); diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java index 6a726cd6ec..4b383556b7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java @@ -28,4 +28,8 @@ public interface TbResourceInfoDao extends Dao { PageData findTenantResourcesByTenantId(UUID tenantId, PageLink pageLink); + PageData findAllTenantResourcesByType(UUID tenantId, String resourceType, PageLink pageLink); + + PageData findTenantResourcesByType(UUID tenantId, String resourceType, PageLink pageLink); + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java index 837ab63fb3..041f774ab9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java @@ -68,4 +68,25 @@ public class JpaTbResourceInfoDao extends JpaAbstractSearchTextDao findAllTenantResourcesByType(UUID tenantId, String resourceType, PageLink pageLink) { + return DaoUtil.toPageData(resourceInfoRepository + .findAllTenantResourcesByType( + tenantId, + TenantId.NULL_UUID, + resourceType, + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink))); + } + + @Override + public PageData findTenantResourcesByType(UUID tenantId, String resourceType, PageLink pageLink) { + return DaoUtil.toPageData(resourceInfoRepository + .findTenantResourcesByType( + tenantId, + resourceType, + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink))); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java index dde66910df..b6a37f5578 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java @@ -46,4 +46,29 @@ public interface TbResourceInfoRepository extends JpaRepository findTenantResourcesByTenantId(@Param("tenantId") UUID tenantId, @Param("searchText") String searchText, Pageable pageable); + + @Query("SELECT tr FROM TbResourceInfoEntity tr WHERE " + + "LOWER(tr.title) LIKE LOWER(CONCAT('%', :searchText, '%'))" + + "AND (tr.tenantId = :tenantId " + + "OR (tr.tenantId = :systemAdminId " + + "AND NOT EXISTS " + + "(SELECT sr FROM TbResourceEntity sr " + + "WHERE sr.tenantId = :tenantId " + + "AND tr.resourceType = sr.resourceType " + + "AND tr.resourceKey = sr.resourceKey)))" + + "AND tr.resourceType = :resourceType") + Page findAllTenantResourcesByType(@Param("tenantId") UUID tenantId, + @Param("systemAdminId") UUID sysadminId, + @Param("resourceType") String resourceType, + @Param("searchText") String searchText, + Pageable pageable); + + @Query("SELECT ri FROM TbResourceInfoEntity ri WHERE " + + "ri.tenantId = :tenantId " + + "AND ri.resourceType = :resourceType " + + "AND LOWER(ri.title) LIKE LOWER(CONCAT('%', :searchText, '%'))") + Page findTenantResourcesByType(@Param("tenantId") UUID tenantId, + @Param("resourceType") String resourceType, + @Param("searchText") String searchText, + Pageable pageable); } From d9663676238703443f51f996c37422c745ee0299 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 17 May 2023 17:07:32 +0300 Subject: [PATCH 058/207] fixed tests --- .../controller/TbResourceControllerTest.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java index dbe0c591e9..fa4beab094 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java @@ -353,7 +353,8 @@ public class TbResourceControllerTest extends AbstractControllerTest { public void testFindSystemTbResourcesByType() throws Exception { loginSysAdmin(); - List resources = new ArrayList<>(); + List jksResources = new ArrayList<>(); + List lwm2mesources = new ArrayList<>(); int jksCntEntity = 17; for (int i = 0; i < jksCntEntity; i++) { TbResource resource = new TbResource(); @@ -361,7 +362,8 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); resource.setData("Test Data"); - resources.add(new TbResourceInfo(save(resource))); + TbResourceInfo saved = new TbResourceInfo(save(resource)); + jksResources.add(saved); } int lwm2mCntEntity = 19; @@ -371,7 +373,8 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setResourceType(ResourceType.PKCS_12); resource.setFileName(i + DEFAULT_FILE_NAME_2); resource.setData("Test Data"); - save(resource); + TbResource saved = save(resource); + lwm2mesources.add(saved); } List loadedResources = new ArrayList<>(); @@ -387,21 +390,21 @@ public class TbResourceControllerTest extends AbstractControllerTest { } } while (pageData.hasNext()); - Collections.sort(resources, idComparator); + Collections.sort(jksResources, idComparator); Collections.sort(loadedResources, idComparator); - Assert.assertEquals(resources, loadedResources); + Assert.assertEquals(jksResources, loadedResources); Mockito.reset(tbClusterService, auditLogService); - int cntEntity = resources.size(); - for (TbResourceInfo resource : resources) { + int cntEntity = jksResources.size(); + for (TbResourceInfo resource : jksResources) { doDelete("/api/resource/" + resource.getId().getId().toString()) .andExpect(status().isOk()); } testNotifyManyEntityManyTimeMsgToEdgeServiceNeverAdditionalInfoAny(new TbResource(), new TbResource(), - resources.get(0).getTenantId(), null, null, SYS_ADMIN_EMAIL, + jksResources.get(0).getTenantId(), null, null, SYS_ADMIN_EMAIL, ActionType.DELETED, cntEntity, 1); pageLink = new PageLink(27); @@ -417,6 +420,13 @@ public class TbResourceControllerTest extends AbstractControllerTest { } while (pageData.hasNext()); Assert.assertTrue(loadedResources.isEmpty()); + + loginSysAdmin(); + + for (TbResourceInfo resource : lwm2mesources) { + doDelete("/api/resource/" + resource.getId().getId().toString()) + .andExpect(status().isOk()); + } } @Test From 21e5a1a130c59955efb33aac757a9fab38174ac3 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 17 May 2023 18:03:35 +0300 Subject: [PATCH 059/207] added logic update to the rule nodes upgrade script --- .../install/ThingsboardInstallService.java | 1 + .../install/SqlDatabaseUpgradeService.java | 19 +++ .../update/DefaultDataUpdateService.java | 139 ++++++++++++------ .../server/dao/rule/RuleChainService.java | 2 + .../server/common/data/rule/RuleNode.java | 6 +- .../server/dao/model/ModelConstants.java | 1 + .../server/dao/model/sql/RuleNodeEntity.java | 5 + .../server/dao/rule/BaseRuleChainService.java | 59 +++++--- .../server/dao/rule/RuleNodeDao.java | 2 + .../server/dao/service/Validator.java | 2 +- .../server/dao/sql/rule/JpaRuleNodeDao.java | 10 ++ .../dao/sql/rule/RuleNodeRepository.java | 6 + .../resources/sql/schema-entities-idx.sql | 2 + .../main/resources/sql/schema-entities.sql | 1 + .../rule/engine/api/VersionedNode.java | 21 +-- .../api/VersionedNodeConfiguration.java | 22 --- .../TbAbstractFetchToNodeConfiguration.java | 4 +- .../metadata/TbAbstractGetEntityAttrNode.java | 10 +- .../metadata/TbAbstractNodeWithFetchTo.java | 17 +-- .../TbFetchDeviceCredentialsNode.java | 18 +-- .../engine/metadata/TbGetAttributesNode.java | 18 +-- .../metadata/TbGetCustomerAttributeNode.java | 14 +- .../metadata/TbGetCustomerDetailsNode.java | 18 +-- .../engine/metadata/TbGetDeviceAttrNode.java | 18 +-- .../metadata/TbGetOriginatorFieldsNode.java | 16 +- .../metadata/TbGetRelatedAttributeNode.java | 12 +- .../metadata/TbGetTenantAttributeNode.java | 12 +- .../metadata/TbGetTenantDetailsNode.java | 18 +-- 28 files changed, 241 insertions(+), 232 deletions(-) delete mode 100644 rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNodeConfiguration.java diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 66867cd90d..80ccd2804a 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -258,6 +258,7 @@ public class ThingsboardInstallService { installScripts.loadSystemLwm2mResources(); case "3.5.0": log.info("Upgrading ThingsBoard from version 3.5.0 to 3.5.1 ..."); + databaseEntitiesUpgradeService.upgradeDatabase("3.5.0"); dataUpdateService.updateData("3.5.0"); log.info("Updating system data..."); systemDataLoaderService.updateSystemWidgets(); diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index 504b058879..c858ecffc4 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -713,6 +713,25 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService log.error("Failed updating schema!!!", e); } break; + case "3.5.0": + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + log.info("Updating schema ..."); + if (isOldSchema(conn, 3005000)) { + try { + conn.createStatement().execute("ALTER TABLE rule_node ADD COLUMN IF NOT EXISTS configuration_version int DEFAULT 0;"); + } catch (Exception e) { + } + try { + conn.createStatement().execute("CREATE INDEX IF NOT EXISTS idx_rule_node_type_configuration_version ON rule_node(type, configuration_version);"); + } catch (Exception e) { + } + conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3005001;"); + } + log.info("Schema updated."); + } catch (Exception e) { + log.error("Failed updating schema!!!", e); + } + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index e5bb70cbbd..0334730e2d 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -22,22 +22,19 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; +import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbNode; +import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.VersionedNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; -import org.thingsboard.rule.engine.metadata.TbFetchDeviceCredentialsNode; -import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; -import org.thingsboard.rule.engine.metadata.TbGetCustomerAttributeNode; -import org.thingsboard.rule.engine.metadata.TbGetCustomerDetailsNode; -import org.thingsboard.rule.engine.metadata.TbGetDeviceAttrNode; -import org.thingsboard.rule.engine.metadata.TbGetOriginatorFieldsNode; -import org.thingsboard.rule.engine.metadata.TbGetRelatedAttributeNode; -import org.thingsboard.rule.engine.metadata.TbGetTenantAttributeNode; -import org.thingsboard.rule.engine.metadata.TbGetTenantDetailsNode; import org.thingsboard.rule.engine.profile.TbDeviceProfileNode; import org.thingsboard.rule.engine.profile.TbDeviceProfileNodeConfiguration; import org.thingsboard.server.common.data.DataConstants; @@ -73,6 +70,7 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.alarm.AlarmDao; import org.thingsboard.server.dao.audit.AuditLogDao; @@ -92,10 +90,13 @@ import org.thingsboard.server.service.install.InstallScripts; import org.thingsboard.server.service.install.SystemDataLoaderService; import org.thingsboard.server.service.install.TbRuleEngineQueueConfigService; +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -107,6 +108,9 @@ import static org.thingsboard.server.common.data.StringUtils.isBlank; @Slf4j public class DefaultDataUpdateService implements DataUpdateService { + @Value("${plugins.scan_packages}") + private String[] scanPackages; + @Autowired private TenantService tenantService; @@ -217,55 +221,96 @@ public class DefaultDataUpdateService implements DataUpdateService { break; case "3.5.0": log.info("Updating data from version 3.5.0 to 3.5.1 ..."); - log.info("Starting enrichment rule nodes update ..."); - upgradeEnrichmentRuleNodesWithFetchTo(); - log.info("Finished enrichment rule nodes update!"); + upgradeRuleNodes(); break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } } - private void upgradeEnrichmentRuleNodesWithFetchTo() { + private void upgradeRuleNodes() { + var ruleChainIdToTenantIdMap = new HashMap(); try { - var ruleChainIdToTenantId = new HashMap(); - upgradeRuleNode(ruleChainIdToTenantId, new TbGetOriginatorFieldsNode()); - upgradeRuleNode(ruleChainIdToTenantId, new TbGetRelatedAttributeNode()); - upgradeRuleNode(ruleChainIdToTenantId, new TbGetTenantAttributeNode()); - upgradeRuleNode(ruleChainIdToTenantId, new TbGetCustomerAttributeNode()); - upgradeRuleNode(ruleChainIdToTenantId, new TbGetAttributesNode()); - upgradeRuleNode(ruleChainIdToTenantId, new TbGetDeviceAttrNode()); - upgradeRuleNode(ruleChainIdToTenantId, new TbGetCustomerDetailsNode()); - upgradeRuleNode(ruleChainIdToTenantId, new TbGetTenantDetailsNode()); - upgradeRuleNode(ruleChainIdToTenantId, new TbFetchDeviceCredentialsNode()); + log.info("Starting rule nodes upgrade ..."); + var ruleNodeDefinitions = getBeanDefinitions( + org.thingsboard.rule.engine.api.RuleNode.class + ); + for (BeanDefinition def : ruleNodeDefinitions) { + String clazzName = def.getBeanClassName(); + Class clazz = Class.forName(clazzName); + TbNode tbNode = (TbNode) clazz.getDeclaredConstructor().newInstance(); + if (tbNode instanceof VersionedNode) { + var versionedNode = (VersionedNode) tbNode; + var ruleNodeName = versionedNode.getClass().getName(); + int currentVersion = versionedNode.getCurrentVersion(); + var ruleNodesToUpdate = new PageDataIterable<>( + pageLink -> + ruleChainService.findAllRuleNodesByTypeAndVersionLessThan(ruleNodeName, currentVersion, pageLink), + 1024 + ); + for (RuleNode ruleNode : ruleNodesToUpdate) { + RuleNodeId ruleNodeId = ruleNode.getId(); + var oldConfiguration = ruleNode.getConfiguration(); + int fromVersion = ruleNode.getConfigurationVersion(); + log.info("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", + ruleNodeId, + clazzName, + fromVersion, + currentVersion); + try { + TbPair upgradeRuleNodeConfigurationResult = versionedNode.upgrade(ruleNodeId, fromVersion, oldConfiguration); + if (upgradeRuleNodeConfigurationResult.getFirst()) { + ruleNode.setConfiguration(upgradeRuleNodeConfigurationResult.getSecond()); + var ruleChainId = ruleNode.getRuleChainId(); + var tenantId = getTenantId(ruleChainIdToTenantIdMap, ruleNodeId, ruleChainId); + if (tenantId == null) { + log.warn("Failed to find tenant id for rule chain with id: {}", ruleChainId); + continue; + } + ruleChainService.saveRuleNode(tenantId, ruleNode); + log.info("Successfully upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", + ruleNodeId, + clazzName, + fromVersion, + currentVersion); + } + } catch (TbNodeException e) { + log.warn("Failed to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {} due to: ", + ruleNodeId, + clazzName, + fromVersion, + currentVersion, + e); + } + } + } + } + log.info("Finished rule nodes upgrade!"); } catch (Exception e) { - log.error("Unexpected error during enrichment rule nodes updating!", e); + log.error("Unexpected error during rule nodes upgrade: ", e); } } - private void upgradeRuleNode(HashMap ruleChainIdToTenantId, VersionedNode versionedNode) { - var ruleNodes = new PageDataIterable<>( - pageLink -> ruleChainService.findAllRuleNodesByType(versionedNode.getClass().getName(), pageLink), 1024 - ); - ruleNodes.forEach(ruleNode -> { - var upgradeRuleNodeConfigurationResult = versionedNode.upgrade(ruleNode.getId(), ruleNode.getConfiguration()); - if (upgradeRuleNodeConfigurationResult.getFirst()) { - ruleNode.setConfiguration(upgradeRuleNodeConfigurationResult.getSecond()); - var ruleChainId = ruleNode.getRuleChainId(); - var tenantId = ruleChainIdToTenantId.computeIfAbsent(ruleChainId, - id -> { - RuleChain ruleChain = ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, id); - if (ruleChain == null) { - log.error("Failed to find rule chain by id: [{}], ruleNodeId: [{}]", ruleChainId, ruleNode.getId()); - return null; - } - return ruleChain.getTenantId(); - }); - if (tenantId != null) { - ruleChainService.saveRuleNode(tenantId, ruleNode); - } - } - }); + private TenantId getTenantId(HashMap ruleChainIdToTenantId, RuleNodeId ruleNodeId, RuleChainId ruleChainId) { + return ruleChainIdToTenantId.computeIfAbsent(ruleChainId, + id -> { + RuleChain ruleChain = ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, id); + if (ruleChain == null) { + log.warn("Failed to find rule chain by id: {} ruleNodeId: {}", ruleChainId, ruleNodeId); + return null; + } + return ruleChain.getTenantId(); + }); + } + + private Set getBeanDefinitions(Class componentType) { + ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); + scanner.addIncludeFilter(new AnnotationTypeFilter(componentType)); + Set defs = new HashSet<>(); + for (String scanPackage : scanPackages) { + defs.addAll(scanner.findCandidateComponents(scanPackage)); + } + return defs; } private final PaginatedUpdater deviceProfileEntityDynamicConditionsUpdater = diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 331fa2e5db..612be9087b 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -99,6 +99,8 @@ public interface RuleChainService extends EntityDaoService { PageData findAllRuleNodesByType(String type, PageLink pageLink); + PageData findAllRuleNodesByTypeAndVersionLessThan(String type, int version, PageLink pageLink); + RuleNode saveRuleNode(TenantId tenantId, RuleNode ruleNode); void deleteRuleNodes(TenantId tenantId, RuleChainId ruleChainId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java index e6041c94f7..f1b55b0e7a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java @@ -50,7 +50,9 @@ public class RuleNode extends SearchTextBasedWithAdditionalInfo impl private boolean debugMode; @ApiModelProperty(position = 7, value = "Enable/disable singleton mode. ", example = "false") private boolean singletonMode; - @ApiModelProperty(position = 8, value = "JSON with the rule node configuration. Structure depends on the rule node implementation.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @ApiModelProperty(position = 8, value = "Version of rule node configuration. ", example = "0") + private int configurationVersion; + @ApiModelProperty(position = 9, value = "JSON with the rule node configuration. Structure depends on the rule node implementation.", dataType = "com.fasterxml.jackson.databind.JsonNode") private transient JsonNode configuration; @JsonIgnore private byte[] configurationBytes; @@ -109,7 +111,7 @@ public class RuleNode extends SearchTextBasedWithAdditionalInfo impl return super.getCreatedTime(); } - @ApiModelProperty(position = 8, value = "Additional parameters of the rule node. Contains 'layoutX' and 'layoutY' properties for visualization.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @ApiModelProperty(position = 10, value = "Additional parameters of the rule node. Contains 'layoutX' and 'layoutY' properties for visualization.", dataType = "com.fasterxml.jackson.databind.JsonNode") @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 122716181c..de356ec3f6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -477,6 +477,7 @@ public class ModelConstants { public static final String RULE_NODE_CHAIN_ID_PROPERTY = "rule_chain_id"; public static final String RULE_NODE_TYPE_PROPERTY = "type"; public static final String RULE_NODE_NAME_PROPERTY = "name"; + public static final String RULE_NODE_VERSION_PROPERTY = "configuration_version"; public static final String RULE_NODE_CONFIGURATION_PROPERTY = "configuration"; /** diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java index 2dce9fb305..af92a09d05 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java @@ -53,6 +53,9 @@ public class RuleNodeEntity extends BaseSqlEntity implements SearchTex @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) private String searchText; + @Column(name = ModelConstants.RULE_NODE_VERSION_PROPERTY) + private int configurationVersion; + @Type(type = "json") @Column(name = ModelConstants.RULE_NODE_CONFIGURATION_PROPERTY) private JsonNode configuration; @@ -86,6 +89,7 @@ public class RuleNodeEntity extends BaseSqlEntity implements SearchTex this.debugMode = ruleNode.isDebugMode(); this.singletonMode = ruleNode.isSingletonMode(); this.searchText = ruleNode.getName(); + this.configurationVersion = ruleNode.getConfigurationVersion(); this.configuration = ruleNode.getConfiguration(); this.additionalInfo = ruleNode.getAdditionalInfo(); if (ruleNode.getExternalId() != null) { @@ -114,6 +118,7 @@ public class RuleNodeEntity extends BaseSqlEntity implements SearchTex ruleNode.setName(name); ruleNode.setDebugMode(debugMode); ruleNode.setSingletonMode(singletonMode); + ruleNode.setConfigurationVersion(configurationVersion); ruleNode.setConfiguration(configuration); ruleNode.setAdditionalInfo(additionalInfo); if (externalId != null) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index a3fe6b39ea..601b6d333e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.VersionedNode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.EntityType; @@ -77,6 +78,7 @@ import java.util.stream.Collectors; import static org.thingsboard.server.common.data.DataConstants.TENANT; import static org.thingsboard.server.dao.service.Validator.validateId; import static org.thingsboard.server.dao.service.Validator.validatePageLink; +import static org.thingsboard.server.dao.service.Validator.validatePositiveNumber; import static org.thingsboard.server.dao.service.Validator.validateString; /** @@ -189,11 +191,11 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC RuleNode savedNode = ruleNodeDao.save(tenantId, node); relations.add(new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); - TbPair upgradeResult = upgradeRuleNode(savedNode); - if (upgradeResult.getFirst()) { - savedNode.setConfiguration(upgradeResult.getSecond()); - savedNode = ruleNodeDao.save(tenantId, savedNode); - } +// TbPair upgradeResult = upgradeRuleNode(savedNode); +// if (upgradeResult.getFirst()) { +// savedNode.setConfiguration(upgradeResult.getSecond()); +// savedNode = ruleNodeDao.save(tenantId, savedNode); +// } int index = nodes.indexOf(node); nodes.set(index, savedNode); ruleNodeIndexMap.put(savedNode.getId(), index); @@ -263,24 +265,38 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC return RuleChainUpdateResult.successful(updatedRuleNodes); } - private TbPair upgradeRuleNode(RuleNode node) { - var configuration = node.getConfiguration(); - String ruleNodeClassName = node.getType(); + private TbPair upgradeRuleNode(RuleNode ruleNode) { + RuleNodeId ruleNodeId = ruleNode.getId(); + String ruleNodeType = ruleNode.getType(); + int fromVersion = ruleNode.getConfigurationVersion(); try { - var ruleNodeClass = Class.forName(ruleNodeClassName).getConstructor().newInstance(); + var ruleNodeClass = Class.forName(ruleNodeType).getDeclaredConstructor().newInstance(); if (ruleNodeClass instanceof VersionedNode) { VersionedNode versionedNode = (VersionedNode) ruleNodeClass; - return versionedNode.upgrade(node.getId(), configuration); + int toVersion = versionedNode.getCurrentVersion(); + log.info("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", + ruleNodeId, + ruleNodeType, + fromVersion, + toVersion); + try { + return versionedNode.upgrade(ruleNodeId, fromVersion, ruleNode.getConfiguration()); + } catch (TbNodeException e) { + log.warn("Failed to upgrade rule node with id: {} fromVersion: {} toVersion: {} due to: ", + ruleNodeId, + fromVersion, + toVersion, + e); + } } - } catch (InstantiationException | - IllegalAccessException | + } catch (ClassNotFoundException | InvocationTargetException | - NoSuchMethodException | - ClassNotFoundException e - ) { - log.warn("Failed to upgrade rule node due to: ", e); + InstantiationException | + IllegalAccessException | + NoSuchMethodException e) { + log.warn("Failed to create instance of rule node with id: {} and type: {}", ruleNodeId, ruleNodeType); } - return new TbPair<>(false, node.getConfiguration()); + return new TbPair<>(false, ruleNode.getConfiguration()); } @Override @@ -728,6 +744,15 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC return ruleNodeDao.findAllRuleNodesByType(type, pageLink); } + @Override + public PageData findAllRuleNodesByTypeAndVersionLessThan(String type, int version, PageLink pageLink) { + log.trace("Executing findAllRuleNodesByTypeAndVersionLessThan, type {}, pageLink {}, version {}", type, pageLink, version); + validateString(type, "Incorrect type of the rule node"); + validatePositiveNumber(version, "Incorrect version to compare with. Version should be greater than 0!"); + validatePageLink(pageLink); + return ruleNodeDao.findAllRuleNodesByTypeAndVersionLessThan(type, version, pageLink); + } + @Override public RuleNode saveRuleNode(TenantId tenantId, RuleNode ruleNode) { return ruleNodeDao.save(tenantId, ruleNode); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java index 880797a981..7df394ddd4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleNodeDao.java @@ -34,6 +34,8 @@ public interface RuleNodeDao extends Dao { PageData findAllRuleNodesByType(String type, PageLink pageLink); + PageData findAllRuleNodesByTypeAndVersionLessThan(String type, int version, PageLink pageLink); + List findByExternalIds(RuleChainId ruleChainId, List externalIds); void deleteByIdIn(List ruleNodeIds); diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java index 0685194d26..e9e664e9c1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java @@ -61,7 +61,7 @@ public class Validator { /** - * This method validate String string. If string is invalid than throw + * This method validate long value. If value isn't possitive than throw * IncorrectParameterException exception * * @param val the val diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java index 1810427c1a..58cf179fea 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java @@ -69,6 +69,16 @@ public class JpaRuleNodeDao extends JpaAbstractSearchTextDao findAllRuleNodesByTypeAndVersionLessThan(String type, int version, PageLink pageLink) { + return DaoUtil.toPageData(ruleNodeRepository + .findAllRuleNodesByTypeAndVersionLessThan( + type, + version, + Objects.toString(pageLink.getTextSearch(), ""), + DaoUtil.toPageable(pageLink))); + } + @Override public List findByExternalIds(RuleChainId ruleChainId, List externalIds) { return DaoUtil.convertDataList(ruleNodeRepository.findRuleNodesByRuleChainIdAndExternalIdIn(ruleChainId.getId(), diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java index 1e157d371f..e016462255 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java @@ -41,6 +41,12 @@ public interface RuleNodeRepository extends JpaRepository @Param("searchText") String searchText, Pageable pageable); + @Query("SELECT r FROM RuleNodeEntity r WHERE r.type = :ruleType AND r.configurationVersion < :version AND LOWER(r.configuration) LIKE LOWER(CONCAT('%', :searchText, '%')) ") + Page findAllRuleNodesByTypeAndVersionLessThan(@Param("ruleType") String ruleType, + @Param("version") int version, + @Param("searchText") String searchText, + Pageable pageable); + List findRuleNodesByRuleChainIdAndExternalIdIn(UUID ruleChainId, List externalIds); @Transactional diff --git a/dao/src/main/resources/sql/schema-entities-idx.sql b/dao/src/main/resources/sql/schema-entities-idx.sql index 4aad5fa1b2..12e0bfddba 100644 --- a/dao/src/main/resources/sql/schema-entities-idx.sql +++ b/dao/src/main/resources/sql/schema-entities-idx.sql @@ -89,6 +89,8 @@ CREATE INDEX IF NOT EXISTS idx_rule_node_external_id ON rule_node(rule_chain_id, CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type); +CREATE INDEX IF NOT EXISTS idx_rule_node_type_configuration_version ON rule_node(type, configuration_version); + CREATE INDEX IF NOT EXISTS idx_api_usage_state_entity_id ON api_usage_state(entity_id); CREATE INDEX IF NOT EXISTS idx_alarm_comment_alarm_id ON alarm_comment(alarm_id); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 52d1d23c6b..6bc73cd9fa 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -184,6 +184,7 @@ CREATE TABLE IF NOT EXISTS rule_node ( created_time bigint NOT NULL, rule_chain_id uuid, additional_info varchar, + configuration_version int DEFAULT 0, configuration varchar(10000000), type varchar(255), name varchar(255), diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java index 51286c00c4..2c442588eb 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java @@ -19,25 +19,10 @@ import com.fasterxml.jackson.databind.JsonNode; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.util.TbPair; -public interface VersionedNode { +public interface VersionedNode extends TbNode { - String VERSION_PROPERTY_NAME = "version"; + TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException; - TbPair upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration); - - default int getVersionOrElseThrowTbNodeException(RuleNodeId ruleNodeId, JsonNode oldConfiguration) throws TbNodeException { - if (oldConfiguration == null) { - throw new TbNodeException("Rule node: [" + this.getClass().getName() + "] " + - "with id: [" + ruleNodeId + "] has null configuration!"); - } else if (!oldConfiguration.isObject()) { - throw new TbNodeException("Rule node: [" + this.getClass().getName() + "] " + - "with id: [" + ruleNodeId + "] has non json object configuration!"); - - } - if (!oldConfiguration.has(VERSION_PROPERTY_NAME)) { - return 0; - } - return oldConfiguration.get(VERSION_PROPERTY_NAME).asInt(); - } + int getCurrentVersion(); } diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNodeConfiguration.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNodeConfiguration.java deleted file mode 100644 index 09e38282e2..0000000000 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNodeConfiguration.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.rule.engine.api; - -public interface VersionedNodeConfiguration { - - int getVersion(); - -} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java index 98970cc4eb..14c27a7ac7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractFetchToNodeConfiguration.java @@ -16,12 +16,10 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; -import org.thingsboard.rule.engine.api.VersionedNodeConfiguration; @Data -public abstract class TbAbstractFetchToNodeConfiguration implements VersionedNodeConfiguration { +public abstract class TbAbstractFetchToNodeConfiguration { private FetchTo fetchTo; - private int version = 1; } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java index 168319b7d6..19127ac5bf 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java @@ -149,11 +149,10 @@ public abstract class TbAbstractGetEntityAttrNode extends Tb ctx.tellSuccess(transformMessage(msg, msgData, msgMetaData)); } - protected TbPair upgradeToUseFetchToAndDataToFetch(RuleNodeId ruleNodeId, JsonNode oldConfiguration) throws TbNodeException { + protected TbPair upgradeToUseFetchToAndDataToFetch(JsonNode oldConfiguration) throws TbNodeException { var newConfigObjectNode = (ObjectNode) oldConfiguration; if (!newConfigObjectNode.has(OLD_PROPERTY_NAME)) { - throw new TbNodeException("Rule node: [" + this.getClass().getName() + "] " + - "with id: [" + ruleNodeId + "] doesn't have property: [" + OLD_PROPERTY_NAME + "]"); + throw new TbNodeException("property to update: '" + OLD_PROPERTY_NAME + "' doesn't exists in configuration!"); } var value = newConfigObjectNode.get(OLD_PROPERTY_NAME).asText(); if ("true".equals(value)) { @@ -163,12 +162,9 @@ public abstract class TbAbstractGetEntityAttrNode extends Tb newConfigObjectNode.remove(OLD_PROPERTY_NAME); newConfigObjectNode.put(DATA_TO_FETCH_PROPERTY_NAME, DataToFetch.ATTRIBUTES.name()); } else { - throw new TbNodeException("Rule node: [" + this.getClass().getName() + "] " + - "with id: [" + ruleNodeId + "] has property: [" + OLD_PROPERTY_NAME + "] " + - "with unexpected value: [" + value + "] Allowed values: true or false!"); + throw new TbNodeException("property to update: '" + OLD_PROPERTY_NAME + "' has unexpected value: " + value + ". Allowed values: true or false!"); } newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, FetchTo.METADATA.name()); - newConfigObjectNode.put(VERSION_PROPERTY_NAME, 1); return new TbPair<>(true, newConfigObjectNode); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java index 229b541863..ebf99765b5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java @@ -36,13 +36,18 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; import java.util.NoSuchElementException; @Slf4j -public abstract class TbAbstractNodeWithFetchTo implements TbNode, VersionedNode { +public abstract class TbAbstractNodeWithFetchTo implements VersionedNode { protected final static String FETCH_TO_PROPERTY_NAME = "fetchTo"; protected C config; protected FetchTo fetchTo; + @Override + public int getCurrentVersion() { + return 1; + } + @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { config = loadNodeConfiguration(configuration); @@ -93,7 +98,6 @@ public abstract class TbAbstractNodeWithFetchTo upgradeRuleNodesWithOldPropertyToUseFetchTo( - RuleNodeId ruleNodeId, JsonNode oldConfiguration, String oldProperty, String ifTrue, @@ -101,24 +105,19 @@ public abstract class TbAbstractNodeWithFetchTo(true, newConfigObjectNode); } else if ("false".equals(value)) { newConfigObjectNode.remove(oldProperty); newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, ifFalse); - newConfigObjectNode.put(VERSION_PROPERTY_NAME, 1); return new TbPair<>(true, newConfigObjectNode); } else { - throw new TbNodeException("Rule node: [" + this.getClass().getName() + "] " + - "with id: [" + ruleNodeId + "] has property: [" + oldProperty + "] " + - "with unexpected value: [" + value + "] Allowed values: true or false!"); + throw new TbNodeException("property to update: '" + oldProperty + "' has unexpected value: " + value + ". Allowed values: true or false!"); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java index 514ad20c5d..2d9804b8d8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java @@ -89,22 +89,14 @@ public class TbFetchDeviceCredentialsNode extends TbAbstractNodeWithFetchTo upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - return upgradeRuleNodesWithOldPropertyToUseFetchTo( - ruleNodeId, + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + return fromVersion == 0 ? + upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, "fetchToMetadata", FetchTo.METADATA.name(), - FetchTo.DATA.name() - ); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); - } - return new TbPair<>(false, oldConfiguration); + FetchTo.DATA.name()) : + new TbPair<>(false, oldConfiguration); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index a4c2a9f3a1..8281db6a26 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -57,22 +57,14 @@ public class TbGetAttributesNode extends TbAbstractGetAttributesNode upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - return upgradeRuleNodesWithOldPropertyToUseFetchTo( - ruleNodeId, + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + return fromVersion == 0 ? + upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, "fetchToData", FetchTo.DATA.name(), - FetchTo.METADATA.name() - ); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); - } - return new TbPair<>(false, oldConfiguration); + FetchTo.METADATA.name()) : + new TbPair<>(false, oldConfiguration); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index 25d4cd8994..eaf197c6a5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -72,16 +72,10 @@ public class TbGetCustomerAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - return upgradeToUseFetchToAndDataToFetch(ruleNodeId, oldConfiguration); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); - } - return new TbPair<>(false, oldConfiguration); + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + return fromVersion == 0 ? + upgradeToUseFetchToAndDataToFetch(oldConfiguration) : + new TbPair<>(false, oldConfiguration); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index 1026d8ca2b..aff1f3b00e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -107,22 +107,14 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - return upgradeRuleNodesWithOldPropertyToUseFetchTo( - ruleNodeId, + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + return fromVersion == 0 ? + upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, "addToMetadata", FetchTo.METADATA.name(), - FetchTo.DATA.name() - ); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); - } - return new TbPair<>(false, oldConfiguration); + FetchTo.DATA.name()) : + new TbPair<>(false, oldConfiguration); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java index dd689ed38d..d47f8445b4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java @@ -60,22 +60,14 @@ public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - return upgradeRuleNodesWithOldPropertyToUseFetchTo( - ruleNodeId, + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + return fromVersion == 0 ? + upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, "fetchToData", FetchTo.DATA.name(), - FetchTo.METADATA.name() - ); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); - } - return new TbPair<>(false, oldConfiguration); + FetchTo.METADATA.name()) : + new TbPair<>(false, oldConfiguration); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java index 93244ef477..4b1f5e1b07 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java @@ -102,17 +102,11 @@ public class TbGetOriginatorFieldsNode extends TbAbstractNodeWithFetchTo upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - var newConfigObjectNode = (ObjectNode) oldConfiguration; - newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, FetchTo.METADATA.name()); - newConfigObjectNode.put(VERSION_PROPERTY_NAME, 1); - return new TbPair<>(true, newConfigObjectNode); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) { + if (fromVersion == 0) { + var newConfigObjectNode = (ObjectNode) oldConfiguration; + newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, FetchTo.METADATA.name()); + return new TbPair<>(true, newConfigObjectNode); } return new TbPair<>(false, oldConfiguration); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index d7fd22d306..3193dee09d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -75,16 +75,8 @@ public class TbGetRelatedAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - return upgradeToUseFetchToAndDataToFetch(ruleNodeId, oldConfiguration); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); - } - return new TbPair<>(false, oldConfiguration); + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index e2ebc6a016..4ae7b1d3a4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -66,16 +66,8 @@ public class TbGetTenantAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - return upgradeToUseFetchToAndDataToFetch(ruleNodeId, oldConfiguration); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); - } - return new TbPair<>(false, oldConfiguration); + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index 31371b8b1c..9d934121b8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -62,22 +62,14 @@ public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode upgrade(RuleNodeId ruleNodeId, JsonNode oldConfiguration) { - try { - int oldVersion = getVersionOrElseThrowTbNodeException(ruleNodeId, oldConfiguration); - if (oldVersion == 0) { - return upgradeRuleNodesWithOldPropertyToUseFetchTo( - ruleNodeId, + public TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + return fromVersion == 0 ? + upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, "addToMetadata", FetchTo.METADATA.name(), - FetchTo.DATA.name() - ); - } - } catch (TbNodeException e) { - log.warn(e.getMessage()); - } - return new TbPair<>(false, oldConfiguration); + FetchTo.DATA.name()) : + new TbPair<>(false, oldConfiguration); } } From 10863881a23ad4503e3bd3d22b4bf2cc084a5740 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Thu, 18 May 2023 13:51:52 +0300 Subject: [PATCH 060/207] UI: Add columns visability for timeseries table --- ...meseries-table-key-settings.component.html | 25 ++++ ...timeseries-table-key-settings.component.ts | 6 +- ...s-table-latest-key-settings.component.html | 25 ++++ ...ies-table-latest-key-settings.component.ts | 6 +- ...eries-table-widget-settings.component.html | 3 + ...eseries-table-widget-settings.component.ts | 2 + .../widget/lib/table-widget.models.ts | 1 + .../lib/timeseries-table-widget.component.ts | 116 ++++++++++++++++-- 8 files changed, 175 insertions(+), 9 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.html index e7ce8a1a02..2dbedf96bd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.html @@ -66,4 +66,29 @@ + + widgets.table.default-column-visibility + + + {{ 'widgets.table.column-visibility-visible' | translate }} + + + {{ 'widgets.table.column-visibility-hidden' | translate }} + + + {{ 'widgets.table.column-visibility-hidden-mobile' | translate }} + + + + + widgets.table.column-selection-to-display + + + {{ 'widgets.table.column-selection-to-display-enabled' | translate }} + + + {{ 'widgets.table.column-selection-to-display-disabled' | translate }} + + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.ts index 722df5bc5f..66a2c8b483 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.ts @@ -43,7 +43,9 @@ export class TimeseriesTableKeySettingsComponent extends WidgetSettingsComponent useCellStyleFunction: false, cellStyleFunction: '', useCellContentFunction: false, - cellContentFunction: '' + cellContentFunction: '', + defaultColumnVisibility: 'visible', + columnSelectionToDisplay: 'enabled' }; } @@ -53,6 +55,8 @@ export class TimeseriesTableKeySettingsComponent extends WidgetSettingsComponent cellStyleFunction: [settings.cellStyleFunction, [Validators.required]], useCellContentFunction: [settings.useCellContentFunction, []], cellContentFunction: [settings.cellContentFunction, [Validators.required]], + defaultColumnVisibility: [settings.defaultColumnVisibility, []], + columnSelectionToDisplay: [settings.columnSelectionToDisplay, []], }); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html index a5b4f6bef2..8fb1629b13 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html @@ -73,4 +73,29 @@ + + widgets.table.default-column-visibility + + + {{ 'widgets.table.column-visibility-visible' | translate }} + + + {{ 'widgets.table.column-visibility-hidden' | translate }} + + + {{ 'widgets.table.column-visibility-hidden-mobile' | translate }} + + + + + widgets.table.column-selection-to-display + + + {{ 'widgets.table.column-selection-to-display-enabled' | translate }} + + + {{ 'widgets.table.column-selection-to-display-disabled' | translate }} + + + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.ts index 70fac42f98..3fe1f1027e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.ts @@ -44,7 +44,9 @@ export class TimeseriesTableLatestKeySettingsComponent extends WidgetSettingsCom useCellStyleFunction: false, cellStyleFunction: '', useCellContentFunction: false, - cellContentFunction: '' + cellContentFunction: '', + defaultColumnVisibility: 'visible', + columnSelectionToDisplay: 'enabled' }; } @@ -56,6 +58,8 @@ export class TimeseriesTableLatestKeySettingsComponent extends WidgetSettingsCom cellStyleFunction: [settings.cellStyleFunction, [Validators.required]], useCellContentFunction: [settings.useCellContentFunction, []], cellContentFunction: [settings.cellContentFunction, [Validators.required]], + defaultColumnVisibility: [settings.defaultColumnVisibility, []], + columnSelectionToDisplay: [settings.columnSelectionToDisplay, []], }); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html index 075cb5583c..ed4428fe45 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html @@ -23,6 +23,9 @@ {{ 'widgets.table.enable-search' | translate }} + + {{ 'widgets.table.enable-select-column-display' | translate }} +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.ts index 273dfbd703..0a57402870 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.ts @@ -41,6 +41,7 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon protected defaultSettings(): WidgetSettings { return { enableSearch: true, + enableSelectColumnDisplay: true, enableStickyHeader: true, enableStickyAction: true, reserveSpaceForHiddenAction: 'true', @@ -59,6 +60,7 @@ export class TimeseriesTableWidgetSettingsComponent extends WidgetSettingsCompon protected onSettingsSet(settings: WidgetSettings) { this.timeseriesTableWidgetSettingsForm = this.fb.group({ enableSearch: [settings.enableSearch, []], + enableSelectColumnDisplay: [settings.enableSelectColumnDisplay, []], enableStickyHeader: [settings.enableStickyHeader, []], enableStickyAction: [settings.enableStickyAction, []], reserveSpaceForHiddenAction: [settings.reserveSpaceForHiddenAction, []], diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts index 3cd343ea57..2a29776e7e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts @@ -31,6 +31,7 @@ type ColumnSelectionOptions = 'enabled' | 'disabled'; export interface TableWidgetSettings { enableSearch: boolean; + enableSelectColumnDisplay: boolean; enableStickyAction: boolean; enableStickyHeader: boolean; displayPagination: boolean; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts index 9aae6523ed..9342a2dc4c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts @@ -19,9 +19,12 @@ import { ChangeDetectorRef, Component, ElementRef, + Injector, Input, + OnDestroy, OnInit, QueryList, + StaticProvider, ViewChild, ViewChildren, ViewContainerRef @@ -64,8 +67,9 @@ import { CellStyleInfo, checkHasActions, constructTableCssString, + DisplayColumn, getCellContentInfo, - getCellStyleInfo, + getCellStyleInfo, getColumnDefaultVisibility, getColumnSelectionAvailability, getRowStyleInfo, getTableCellButtonActions, noDataMessage, @@ -75,12 +79,17 @@ import { TableWidgetDataKeySettings, TableWidgetSettings } from '@home/components/widget/lib/table-widget.models'; -import { Overlay } from '@angular/cdk/overlay'; +import { ConnectedPosition, Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; import { SubscriptionEntityInfo } from '@core/api/widget-api.models'; import { DatePipe } from '@angular/common'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { ResizeObserver } from '@juggle/resize-observer'; import { hidePageSizePixelValue } from '@shared/models/constants'; +import { + DISPLAY_COLUMNS_PANEL_DATA, + DisplayColumnsPanelComponent +} from '@home/components/widget/lib/display-columns-panel.component'; +import { ComponentPortal } from '@angular/cdk/portal'; export interface TimeseriesTableWidgetSettings extends TableWidgetSettings { showTimestamp: boolean; @@ -105,6 +114,8 @@ interface TimeseriesHeader { dataKey: DataKey; sortable: boolean; show: boolean; + columnDefaultVisibility?: boolean; + columnSelectionAvailability?: boolean; styleInfo: CellStyleInfo; contentInfo: CellContentInfo; order?: number; @@ -131,7 +142,7 @@ interface TimeseriesTableSource { templateUrl: './timeseries-table-widget.component.html', styleUrls: ['./timeseries-table-widget.component.scss', './table-widget.scss'] }) -export class TimeseriesTableWidgetComponent extends PageComponent implements OnInit, AfterViewInit { +export class TimeseriesTableWidgetComponent extends PageComponent implements OnInit, AfterViewInit, OnDestroy { @Input() ctx: WidgetContext; @@ -169,6 +180,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI private useEntityLabel = false; private dateFormatFilter: string; + private displayedColumns: Array = []; + private rowStylesInfo: RowStyleInfo; private subscriptions: Subscription[] = []; @@ -184,6 +197,15 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI } }; + private columnDisplayAction: WidgetAction = { + name: 'entity.columns-to-display', + show: true, + icon: 'view_column', + onAction: ($event) => { + this.editColumnsToDisplay($event); + } + }; + constructor(protected store: Store, private elementRef: ElementRef, private overlay: Overlay, @@ -275,11 +297,12 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI } private initialize() { - this.ctx.widgetActions = [this.searchAction ]; + this.ctx.widgetActions = [this.searchAction, this.columnDisplayAction]; this.setCellButtonAction = !!this.ctx.actionsApi.getActionDescriptors('actionCellButton').length; this.searchAction.show = isDefined(this.settings.enableSearch) ? this.settings.enableSearch : true; + this.columnDisplayAction.show = isDefined(this.settings.enableSelectColumnDisplay) ? this.settings.enableSelectColumnDisplay : true; this.displayPagination = isDefined(this.settings.displayPagination) ? this.settings.displayPagination : true; this.enableStickyHeader = isDefined(this.settings.enableStickyHeader) ? this.settings.enableStickyHeader : true; this.enableStickyAction = isDefined(this.settings.enableStickyAction) ? this.settings.enableStickyAction : true; @@ -365,9 +388,82 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI this.sources.push(source); } } + this.prepareDisplayedColumn(); + this.sources[this.sourceIndex].displayedColumns = + this.displayedColumns[this.sourceIndex].filter(value => value.display).map(value => value.def); this.updateActiveEntityInfo(); } + private editColumnsToDisplay($event: Event) { + if ($event) { + $event.stopPropagation(); + } + const target = $event.target || $event.currentTarget; + const config = new OverlayConfig(); + config.backdropClass = 'cdk-overlay-transparent-backdrop'; + config.hasBackdrop = true; + const connectedPosition: ConnectedPosition = { + originX: 'end', + originY: 'bottom', + overlayX: 'end', + overlayY: 'top' + }; + config.positionStrategy = this.overlay.position().flexibleConnectedTo(target as HTMLElement) + .withPositions([connectedPosition]); + + const overlayRef = this.overlay.create(config); + overlayRef.backdropClick().subscribe(() => { + overlayRef.dispose(); + }); + const source = this.sources[this.sourceIndex]; + + this.prepareDisplayedColumn(); + + const providers: StaticProvider[] = [ + { + provide: DISPLAY_COLUMNS_PANEL_DATA, + useValue: { + columns: this.displayedColumns[this.sourceIndex], + columnsUpdated: (newColumns) => { + source.displayedColumns = newColumns.filter(value => value.display).map(value => value.def); + this.clearCache(); + } + } + }, + { + provide: OverlayRef, + useValue: overlayRef + } + ]; + + const injector = Injector.create({parent: this.viewContainerRef.injector, providers}); + overlayRef.attach(new ComponentPortal(DisplayColumnsPanelComponent, + this.viewContainerRef, injector)); + this.ctx.detectChanges(); + } + + private prepareDisplayedColumn() { + if (!this.displayedColumns[this.sourceIndex]) { + this.displayedColumns[this.sourceIndex] = this.sources[this.sourceIndex].displayedColumns.map(value => { + let title = ''; + const header = this.sources[this.sourceIndex].header.find(column => column.index.toString() === value); + if (value === '0') { + title = 'Timestamp'; + } else if (value === 'actions') { + title = 'Actions'; + } else { + title = header.dataKey.name; + } + return { + title, + def: value, + display: header?.columnDefaultVisibility ?? true, + selectable: header?.columnSelectionAvailability ?? true + }; + }); + } + } + private prepareHeader(datasource: Datasource): TimeseriesHeader[] { const dataKeys = datasource.dataKeys; const latestDataKeys = datasource.latestDataKeys; @@ -377,6 +473,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI const keySettings: TableWidgetDataKeySettings = dataKey.settings; const styleInfo = getCellStyleInfo(keySettings, 'value, rowData, ctx'); const contentInfo = getCellContentInfo(keySettings, 'value, rowData, ctx'); + const columnDefaultVisibility = getColumnDefaultVisibility(keySettings, this.ctx); + const columnSelectionAvailability = getColumnSelectionAvailability(keySettings); contentInfo.units = dataKey.units; contentInfo.decimals = dataKey.decimals; header.push({ @@ -386,6 +484,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI styleInfo, contentInfo, show: true, + columnDefaultVisibility, + columnSelectionAvailability, order: index + 2 }); }); @@ -396,6 +496,8 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI const keySettings: TimeseriesWidgetLatestDataKeySettings = dataKey.settings; const styleInfo = getCellStyleInfo(keySettings, 'value, rowData, ctx'); const contentInfo = getCellContentInfo(keySettings, 'value, rowData, ctx'); + const columnDefaultVisibility = getColumnDefaultVisibility(keySettings, this.ctx); + const columnSelectionAvailability = getColumnSelectionAvailability(keySettings); contentInfo.units = dataKey.units; contentInfo.decimals = dataKey.decimals; header.push({ @@ -405,13 +507,13 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI styleInfo, contentInfo, show: isDefinedAndNotNull(keySettings.show) ? keySettings.show : true, + columnDefaultVisibility, + columnSelectionAvailability, order: isDefinedAndNotNull(keySettings.order) ? keySettings.order : (index + 2) }); }); } - header = header.sort((a, b) => { - return a.order - b.order; - }); + header = header.sort((a, b) => a.order - b.order); return header; } From 49c230c81568cc8d19a412b74a06803d929bb2f4 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 18 May 2023 17:58:45 +0300 Subject: [PATCH 061/207] refactoring --- .../controller/TbResourceController.java | 12 ++----- .../resource/DefaultTbResourceService.java | 18 +++-------- .../service/resource/TbResourceService.java | 8 ++--- .../sql/BaseTbResourceServiceTest.java | 10 +++--- .../server/dao/resource/ResourceService.java | 8 ++--- .../dao/resource/BaseResourceService.java | 22 +++---------- .../dao/resource/TbResourceInfoDao.java | 8 ++--- .../sql/resource/JpaTbResourceInfoDao.java | 24 ++------------ .../resource/TbResourceInfoRepository.java | 32 ++++--------------- .../server/dao/service/TenantServiceTest.java | 2 +- 10 files changed, 31 insertions(+), 113 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index 316599a092..6118794095 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -167,17 +167,9 @@ public class TbResourceController extends BaseController { @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { - if (StringUtils.isNotEmpty(resourceType)){ - return checkNotNull(resourceService.findTenantResourcesByType(getTenantId(), ResourceType.valueOf(resourceType), pageLink)); - } else { - return checkNotNull(resourceService.findTenantResourcesByTenantId(getTenantId(), pageLink)); - } + return checkNotNull(resourceService.findTenantResourcesByTenantId(getTenantId(), StringUtils.isNotEmpty(resourceType) ? ResourceType.valueOf(resourceType) : null, pageLink)); } else { - if (StringUtils.isNotEmpty(resourceType)){ - return checkNotNull(resourceService.findAllTenantResourcesByType(getTenantId(), ResourceType.valueOf(resourceType), pageLink)); - } else { - return checkNotNull(resourceService.findAllTenantResourcesByTenantId(getTenantId(), pageLink)); - } + return checkNotNull(resourceService.findAllTenantResourcesByTenantId(getTenantId(), StringUtils.isNotEmpty(resourceType) ? ResourceType.valueOf(resourceType) : null, pageLink)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java index ece58397ab..de01c9bf54 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java @@ -76,23 +76,13 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements } @Override - public PageData findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) { - return resourceService.findAllTenantResourcesByTenantId(tenantId, pageLink); + public PageData findAllTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { + return resourceService.findAllTenantResourcesByTenantId(tenantId, resourceType, pageLink); } @Override - public PageData findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) { - return resourceService.findTenantResourcesByTenantId(tenantId, pageLink); - } - - @Override - public PageData findAllTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { - return resourceService.findAllTenantResourcesByType(tenantId, resourceType, pageLink); - } - - @Override - public PageData findTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { - return resourceService.findTenantResourcesByType(tenantId, resourceType, pageLink); + public PageData findTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { + return resourceService.findTenantResourcesByTenantId(tenantId, resourceType, pageLink); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java index c3b6506abe..6e26d9ffe8 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java @@ -35,13 +35,9 @@ public interface TbResourceService extends SimpleTbEntityService { TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId); - PageData findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); + PageData findAllTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink); - PageData findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); - - PageData findAllTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink); - - PageData findTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + PageData findTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink); List findLwM2mObject(TenantId tenantId, String sortOrder, diff --git a/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java b/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java index e2c5985553..364850e2fd 100644 --- a/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java @@ -356,7 +356,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { PageLink pageLink = new PageLink(16); PageData pageData; do { - pageData = resourceService.findTenantResourcesByTenantId(tenantId, pageLink); + pageData = resourceService.findTenantResourcesByTenantId(tenantId, null, pageLink); loadedResources.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink(); @@ -371,7 +371,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resourceService.deleteResourcesByTenantId(tenantId); pageLink = new PageLink(31); - pageData = resourceService.findTenantResourcesByTenantId(tenantId, pageLink); + pageData = resourceService.findTenantResourcesByTenantId(tenantId, null, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertTrue(pageData.getData().isEmpty()); @@ -417,7 +417,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { PageLink pageLink = new PageLink(10); PageData pageData; do { - pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, pageLink); + pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, null, pageLink); loadedResources.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink(); @@ -432,14 +432,14 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resourceService.deleteResourcesByTenantId(tenantId); pageLink = new PageLink(100); - pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, pageLink); + pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, null, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(pageData.getData().size(), 100); resourceService.deleteResourcesByTenantId(TenantId.SYS_TENANT_ID); pageLink = new PageLink(100); - pageData = resourceService.findAllTenantResourcesByTenantId(TenantId.SYS_TENANT_ID, pageLink); + pageData = resourceService.findAllTenantResourcesByTenantId(TenantId.SYS_TENANT_ID, null, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertTrue(pageData.getData().isEmpty()); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 779fbaf275..2933c1a3c2 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -39,13 +39,9 @@ public interface ResourceService extends EntityDaoService { ListenableFuture findResourceInfoByIdAsync(TenantId tenantId, TbResourceId resourceId); - PageData findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); + PageData findAllTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink); - PageData findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); - - PageData findAllTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink); - - PageData findTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + PageData findTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink); List findTenantResourcesByResourceTypeAndObjectIds(TenantId tenantId, ResourceType lwm2mModel, String[] objectIds); diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 3bc02f0a5a..1e14e11f74 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -103,31 +103,17 @@ public class BaseResourceService implements ResourceService { } @Override - public PageData findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) { + public PageData findAllTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { log.trace("Executing findAllTenantResourcesByTenantId [{}]", tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - return resourceInfoDao.findAllTenantResourcesByTenantId(tenantId.getId(), pageLink); + return resourceInfoDao.findAllTenantResourcesByTenantId(tenantId.getId(), resourceType == null ? null : resourceType.name(), pageLink); } @Override - public PageData findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink) { + public PageData findTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { log.trace("Executing findTenantResourcesByTenantId [{}]", tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - return resourceInfoDao.findTenantResourcesByTenantId(tenantId.getId(), pageLink); - } - - @Override - public PageData findAllTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { - log.trace("Executing findAllTenantResourcesByType [{}]", tenantId); - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - return resourceInfoDao.findAllTenantResourcesByType(tenantId.getId(), resourceType.name(), pageLink); - } - - @Override - public PageData findTenantResourcesByType(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { - log.trace("Executing findTenantResourcesByType [{}]", tenantId); - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - return resourceInfoDao.findTenantResourcesByType(tenantId.getId(), resourceType.name(), pageLink); + return resourceInfoDao.findTenantResourcesByTenantId(tenantId.getId(), resourceType == null ? null : resourceType.name(), pageLink); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java index 4b383556b7..e916ff6b71 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java @@ -24,12 +24,8 @@ import java.util.UUID; public interface TbResourceInfoDao extends Dao { - PageData findAllTenantResourcesByTenantId(UUID tenantId, PageLink pageLink); + PageData findAllTenantResourcesByTenantId(UUID tenantId, String resourceType, PageLink pageLink); - PageData findTenantResourcesByTenantId(UUID tenantId, PageLink pageLink); - - PageData findAllTenantResourcesByType(UUID tenantId, String resourceType, PageLink pageLink); - - PageData findTenantResourcesByType(UUID tenantId, String resourceType, PageLink pageLink); + PageData findTenantResourcesByTenantId(UUID tenantId, String resourceType, PageLink pageLink); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java index 041f774ab9..16154976c2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java @@ -51,42 +51,24 @@ public class JpaTbResourceInfoDao extends JpaAbstractSearchTextDao findAllTenantResourcesByTenantId(UUID tenantId, PageLink pageLink) { + public PageData findAllTenantResourcesByTenantId(UUID tenantId, String resourceType, PageLink pageLink) { return DaoUtil.toPageData(resourceInfoRepository .findAllTenantResourcesByTenantId( tenantId, TenantId.NULL_UUID, + resourceType, Objects.toString(pageLink.getTextSearch(), ""), DaoUtil.toPageable(pageLink))); } @Override - public PageData findTenantResourcesByTenantId(UUID tenantId, PageLink pageLink) { + public PageData findTenantResourcesByTenantId(UUID tenantId, String resourceType, PageLink pageLink) { return DaoUtil.toPageData(resourceInfoRepository .findTenantResourcesByTenantId( tenantId, - Objects.toString(pageLink.getTextSearch(), ""), - DaoUtil.toPageable(pageLink))); - } - - @Override - public PageData findAllTenantResourcesByType(UUID tenantId, String resourceType, PageLink pageLink) { - return DaoUtil.toPageData(resourceInfoRepository - .findAllTenantResourcesByType( - tenantId, - TenantId.NULL_UUID, resourceType, Objects.toString(pageLink.getTextSearch(), ""), DaoUtil.toPageable(pageLink))); } - @Override - public PageData findTenantResourcesByType(UUID tenantId, String resourceType, PageLink pageLink) { - return DaoUtil.toPageData(resourceInfoRepository - .findTenantResourcesByType( - tenantId, - resourceType, - Objects.toString(pageLink.getTextSearch(), ""), - DaoUtil.toPageable(pageLink))); - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java index b6a37f5578..57adba882d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java @@ -34,41 +34,21 @@ public interface TbResourceInfoRepository extends JpaRepository findAllTenantResourcesByTenantId(@Param("tenantId") UUID tenantId, @Param("systemAdminId") UUID sysadminId, + @Param("resourceType") String resourceType, @Param("searchText") String searchText, Pageable pageable); @Query("SELECT ri FROM TbResourceInfoEntity ri WHERE " + "ri.tenantId = :tenantId " + - "AND LOWER(ri.title) LIKE LOWER(CONCAT('%', :searchText, '%'))") + "AND LOWER(ri.title) LIKE LOWER(CONCAT('%', :searchText, '%'))" + + "AND (:resourceType is null or ri.resourceType = :resourceType)") Page findTenantResourcesByTenantId(@Param("tenantId") UUID tenantId, + @Param("resourceType") String resourceType, @Param("searchText") String searchText, Pageable pageable); - @Query("SELECT tr FROM TbResourceInfoEntity tr WHERE " + - "LOWER(tr.title) LIKE LOWER(CONCAT('%', :searchText, '%'))" + - "AND (tr.tenantId = :tenantId " + - "OR (tr.tenantId = :systemAdminId " + - "AND NOT EXISTS " + - "(SELECT sr FROM TbResourceEntity sr " + - "WHERE sr.tenantId = :tenantId " + - "AND tr.resourceType = sr.resourceType " + - "AND tr.resourceKey = sr.resourceKey)))" + - "AND tr.resourceType = :resourceType") - Page findAllTenantResourcesByType(@Param("tenantId") UUID tenantId, - @Param("systemAdminId") UUID sysadminId, - @Param("resourceType") String resourceType, - @Param("searchText") String searchText, - Pageable pageable); - - @Query("SELECT ri FROM TbResourceInfoEntity ri WHERE " + - "ri.tenantId = :tenantId " + - "AND ri.resourceType = :resourceType " + - "AND LOWER(ri.title) LIKE LOWER(CONCAT('%', :searchText, '%'))") - Page findTenantResourcesByType(@Param("tenantId") UUID tenantId, - @Param("resourceType") String resourceType, - @Param("searchText") String searchText, - Pageable pageable); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java index 2c7674c81b..74af3c0850 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java @@ -506,7 +506,7 @@ public class TenantServiceTest extends AbstractServiceTest { .as("resource").isNull(); PageLink pageLinkResources = new PageLink(1); PageData tenantResources = - resourceService.findAllTenantResourcesByTenantId(tenant.getId(), pageLinkResources); + resourceService.findAllTenantResourcesByTenantId(tenant.getId(), null, pageLinkResources); Assert.assertEquals(0, tenantResources.getTotalElements()); } From 6d78fe484c41fbedcf40037b57af49deba3684c9 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 18 May 2023 18:01:09 +0300 Subject: [PATCH 062/207] minor refactoring --- .../thingsboard/server/controller/TbResourceController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index 6118794095..ab48214981 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -166,10 +166,11 @@ public class TbResourceController extends BaseController { @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); + ResourceType resourceTypeValue = StringUtils.isNotEmpty(resourceType) ? ResourceType.valueOf(resourceType) : null; if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { - return checkNotNull(resourceService.findTenantResourcesByTenantId(getTenantId(), StringUtils.isNotEmpty(resourceType) ? ResourceType.valueOf(resourceType) : null, pageLink)); + return checkNotNull(resourceService.findTenantResourcesByTenantId(getTenantId(), resourceTypeValue, pageLink)); } else { - return checkNotNull(resourceService.findAllTenantResourcesByTenantId(getTenantId(), StringUtils.isNotEmpty(resourceType) ? ResourceType.valueOf(resourceType) : null, pageLink)); + return checkNotNull(resourceService.findAllTenantResourcesByTenantId(getTenantId(), resourceTypeValue, pageLink)); } } From 45e1a17be34355b8155335e45c7e1c91f34f931d Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 18 May 2023 18:30:50 +0300 Subject: [PATCH 063/207] refactoring --- .../server/dao/sql/resource/TbResourceInfoRepository.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java index 57adba882d..720b78a5f5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/TbResourceInfoRepository.java @@ -35,7 +35,7 @@ public interface TbResourceInfoRepository extends JpaRepository findAllTenantResourcesByTenantId(@Param("tenantId") UUID tenantId, @Param("systemAdminId") UUID sysadminId, @Param("resourceType") String resourceType, @@ -44,8 +44,8 @@ public interface TbResourceInfoRepository extends JpaRepository findTenantResourcesByTenantId(@Param("tenantId") UUID tenantId, @Param("resourceType") String resourceType, @Param("searchText") String searchText, From cfcf539c5048ece226760f47aeb774f91c28271f Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 18 May 2023 18:55:00 +0300 Subject: [PATCH 064/207] added upgrade logic tests && added fixes for review comments --- .../server/ThingsboardInstallApplication.java | 1 + .../bean/AnnotationBeanDiscoveryService.java | 45 ++++++ .../service/bean/BeanDiscoveryService.java | 27 ++++ .../AnnotationComponentDiscoveryService.java | 23 +--- .../update/DefaultDataUpdateService.java | 128 ++++++++---------- .../controller/RuleChainControllerTest.java | 79 +++++++++++ .../server/dao/rule/BaseRuleChainService.java | 97 +++++++------ ...ersionedNode.java => TbVersionedNode.java} | 5 +- .../metadata/TbAbstractNodeWithFetchTo.java | 6 +- .../TbFetchDeviceCredentialsNode.java | 3 +- .../engine/metadata/TbGetAttributesNode.java | 3 +- .../metadata/TbGetCustomerAttributeNode.java | 3 +- .../metadata/TbGetCustomerDetailsNode.java | 3 +- .../engine/metadata/TbGetDeviceAttrNode.java | 3 +- .../metadata/TbGetOriginatorFieldsNode.java | 3 +- .../metadata/TbGetRelatedAttributeNode.java | 3 +- .../metadata/TbGetTenantAttributeNode.java | 3 +- .../metadata/TbGetTenantDetailsNode.java | 3 +- .../TbFetchDeviceCredentialsNodeTest.java | 14 +- .../metadata/TbGetAttributesNodeTest.java | 20 +++ .../TbGetCustomerAttributeNodeTest.java | 14 ++ .../TbGetCustomerDetailsNodeTest.java | 14 ++ .../metadata/TbGetDeviceAttrNodeTest.java | 45 ++++++ .../TbGetOriginatorFieldsNodeTest.java | 14 ++ .../TbGetRelatedAttributeNodeTest.java | 18 +++ .../TbGetTenantAttributeNodeTest.java | 14 ++ .../metadata/TbGetTenantDetailsNodeTest.java | 14 ++ .../rulechain/rulechain-page.component.ts | 2 + .../src/app/shared/models/rule-node.models.ts | 1 + 29 files changed, 451 insertions(+), 157 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java create mode 100644 application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java rename rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/{VersionedNode.java => TbVersionedNode.java} (77%) create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java index b780f0e8cd..b99674f416 100644 --- a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java +++ b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java @@ -27,6 +27,7 @@ import java.util.Arrays; @Slf4j @SpringBootConfiguration @ComponentScan({"org.thingsboard.server.install", + "org.thingsboard.server.service.bean", "org.thingsboard.server.service.component", "org.thingsboard.server.service.install", "org.thingsboard.server.service.security.auth.jwt.settings", diff --git a/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java new file mode 100644 index 0000000000..3ee1c14540 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.bean; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.filter.AnnotationTypeFilter; +import org.springframework.stereotype.Service; + +import java.lang.annotation.Annotation; +import java.util.HashSet; +import java.util.Set; + +@Service +public class AnnotationBeanDiscoveryService implements BeanDiscoveryService { + + @Value("${plugins.scan_packages}") + private String[] scanPackages; + + @Override + public Set discoverBeansByAnnotationType(Class annotationType) { + ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); + scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType)); + Set defs = new HashSet<>(); + for (String scanPackage : scanPackages) { + defs.addAll(scanner.findCandidateComponents(scanPackage)); + } + return defs; + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java new file mode 100644 index 0000000000..5ca615a94d --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java @@ -0,0 +1,27 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.bean; + +import org.springframework.beans.factory.config.BeanDefinition; + +import java.lang.annotation.Annotation; +import java.util.Set; + +public interface BeanDiscoveryService { + + Set discoverBeansByAnnotationType(Class annotationType); + +} diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index b425694e81..d4c6e7a18c 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -20,12 +20,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.env.Environment; import org.springframework.core.env.Profiles; -import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.rule.engine.api.NodeDefinition; @@ -36,14 +33,13 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.dao.component.ComponentDescriptorService; +import org.thingsboard.server.service.bean.BeanDiscoveryService; import javax.annotation.PostConstruct; -import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -54,12 +50,13 @@ import java.util.Set; public class AnnotationComponentDiscoveryService implements ComponentDiscoveryService { public static final int MAX_OPTIMISITC_RETRIES = 3; - @Value("${plugins.scan_packages}") - private String[] scanPackages; @Autowired private Environment environment; + @Autowired(required = false) + private BeanDiscoveryService beanDiscoveryService; + @Autowired private ComponentDescriptorService componentDescriptorService; @@ -83,7 +80,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe } private void registerRuleNodeComponents() { - Set ruleNodeBeanDefinitions = getBeanDefinitions(RuleNode.class); + Set ruleNodeBeanDefinitions = beanDiscoveryService.discoverBeansByAnnotationType(RuleNode.class); for (BeanDefinition def : ruleNodeBeanDefinitions) { int retryCount = 0; Exception cause = null; @@ -212,16 +209,6 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe return relationTypes.toArray(new String[relationTypes.size()]); } - private Set getBeanDefinitions(Class componentType) { - ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); - scanner.addIncludeFilter(new AnnotationTypeFilter(componentType)); - Set defs = new HashSet<>(); - for (String scanPackage : scanPackages) { - defs.addAll(scanner.findCandidateComponents(scanPackage)); - } - return defs; - } - @Override public void discoverComponents() { registerRuleNodeComponents(); diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 0334730e2d..c896e10dc3 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -17,22 +17,18 @@ package org.thingsboard.server.service.install.update; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; -import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.rule.engine.api.VersionedNode; +import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; import org.thingsboard.rule.engine.profile.TbDeviceProfileNode; @@ -86,17 +82,14 @@ import org.thingsboard.server.dao.sql.device.DeviceProfileRepository; import org.thingsboard.server.dao.tenant.TenantProfileService; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.timeseries.TimeseriesService; +import org.thingsboard.server.service.bean.BeanDiscoveryService; import org.thingsboard.server.service.install.InstallScripts; import org.thingsboard.server.service.install.SystemDataLoaderService; -import org.thingsboard.server.service.install.TbRuleEngineQueueConfigService; -import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -108,9 +101,6 @@ import static org.thingsboard.server.common.data.StringUtils.isBlank; @Slf4j public class DefaultDataUpdateService implements DataUpdateService { - @Value("${plugins.scan_packages}") - private String[] scanPackages; - @Autowired private TenantService tenantService; @@ -149,7 +139,7 @@ public class DefaultDataUpdateService implements DataUpdateService { private QueueService queueService; @Autowired - private TbRuleEngineQueueConfigService queueConfig; + private BeanDiscoveryService beanDiscoveryService; @Autowired private SystemDataLoaderService systemDataLoaderService; @@ -229,57 +219,54 @@ public class DefaultDataUpdateService implements DataUpdateService { } private void upgradeRuleNodes() { - var ruleChainIdToTenantIdMap = new HashMap(); try { - log.info("Starting rule nodes upgrade ..."); - var ruleNodeDefinitions = getBeanDefinitions( - org.thingsboard.rule.engine.api.RuleNode.class - ); - for (BeanDefinition def : ruleNodeDefinitions) { - String clazzName = def.getBeanClassName(); - Class clazz = Class.forName(clazzName); - TbNode tbNode = (TbNode) clazz.getDeclaredConstructor().newInstance(); - if (tbNode instanceof VersionedNode) { - var versionedNode = (VersionedNode) tbNode; - var ruleNodeName = versionedNode.getClass().getName(); - int currentVersion = versionedNode.getCurrentVersion(); - var ruleNodesToUpdate = new PageDataIterable<>( - pageLink -> - ruleChainService.findAllRuleNodesByTypeAndVersionLessThan(ruleNodeName, currentVersion, pageLink), - 1024 - ); + log.info("Lookup rule nodes to upgrade ..."); + ArrayList tbVersionedNodes = getTbVersionedNodes(); + log.info("Found {} versioned nodes to check for upgrade!", tbVersionedNodes.size()); + for (TbVersionedNode tbVersionedNode : tbVersionedNodes) { + String ruleNodeType = tbVersionedNode.getClass().getName(); + String ruleNodeTypeForLogs = tbVersionedNode.getClass().getSimpleName(); + int toVersion = tbVersionedNode.getCurrentVersion(); + log.info("Going to check for nodes with type: {} to upgrade to version: {}.", ruleNodeTypeForLogs, toVersion); + var ruleNodesToUpdate = new PageDataIterable<>( + pageLink -> + ruleChainService.findAllRuleNodesByTypeAndVersionLessThan( + ruleNodeType, + toVersion, + pageLink + ), + 1024 + ); + if (Iterables.isEmpty(ruleNodesToUpdate)) { + log.info("There are no active nodes with type: {}, or all nodes with this type already set to latest version!", ruleNodeTypeForLogs); + } else { for (RuleNode ruleNode : ruleNodesToUpdate) { RuleNodeId ruleNodeId = ruleNode.getId(); var oldConfiguration = ruleNode.getConfiguration(); int fromVersion = ruleNode.getConfigurationVersion(); log.info("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", ruleNodeId, - clazzName, + ruleNodeTypeForLogs, fromVersion, - currentVersion); + toVersion); try { - TbPair upgradeRuleNodeConfigurationResult = versionedNode.upgrade(ruleNodeId, fromVersion, oldConfiguration); + TbPair upgradeRuleNodeConfigurationResult = tbVersionedNode.upgrade(fromVersion, oldConfiguration); if (upgradeRuleNodeConfigurationResult.getFirst()) { ruleNode.setConfiguration(upgradeRuleNodeConfigurationResult.getSecond()); - var ruleChainId = ruleNode.getRuleChainId(); - var tenantId = getTenantId(ruleChainIdToTenantIdMap, ruleNodeId, ruleChainId); - if (tenantId == null) { - log.warn("Failed to find tenant id for rule chain with id: {}", ruleChainId); - continue; - } - ruleChainService.saveRuleNode(tenantId, ruleNode); - log.info("Successfully upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", - ruleNodeId, - clazzName, - fromVersion, - currentVersion); } + ruleNode.setConfigurationVersion(toVersion); + ruleChainService.saveRuleNode(TenantId.SYS_TENANT_ID, ruleNode); + log.info("Successfully upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", + ruleNodeId, + ruleNodeTypeForLogs, + fromVersion, + toVersion); } catch (TbNodeException e) { log.warn("Failed to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {} due to: ", ruleNodeId, - clazzName, + ruleNodeTypeForLogs, fromVersion, - currentVersion, + toVersion, e); } } @@ -290,27 +277,28 @@ public class DefaultDataUpdateService implements DataUpdateService { log.error("Unexpected error during rule nodes upgrade: ", e); } } - - private TenantId getTenantId(HashMap ruleChainIdToTenantId, RuleNodeId ruleNodeId, RuleChainId ruleChainId) { - return ruleChainIdToTenantId.computeIfAbsent(ruleChainId, - id -> { - RuleChain ruleChain = ruleChainService.findRuleChainById(TenantId.SYS_TENANT_ID, id); - if (ruleChain == null) { - log.warn("Failed to find rule chain by id: {} ruleNodeId: {}", ruleChainId, ruleNodeId); - return null; - } - return ruleChain.getTenantId(); - }); - } - - private Set getBeanDefinitions(Class componentType) { - ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); - scanner.addIncludeFilter(new AnnotationTypeFilter(componentType)); - Set defs = new HashSet<>(); - for (String scanPackage : scanPackages) { - defs.addAll(scanner.findCandidateComponents(scanPackage)); + private ArrayList getTbVersionedNodes() { + var ruleNodeDefinitions = beanDiscoveryService.discoverBeansByAnnotationType( + org.thingsboard.rule.engine.api.RuleNode.class + ); + var tbVersionedNodes = new ArrayList(); + for (var def : ruleNodeDefinitions) { + String clazzName = def.getBeanClassName(); + try { + var clazz = Class.forName(clazzName); + if (TbVersionedNode.class.isAssignableFrom(clazz)) { + tbVersionedNodes.add((TbVersionedNode) clazz.getDeclaredConstructor().newInstance()); + } + } catch (NoSuchMethodException | + InstantiationException | + IllegalAccessException | + InvocationTargetException | + ClassNotFoundException e + ) { + log.warn("Failed to create instance of rule node type: {} due to: ", clazzName, e); + } } - return defs; + return tbVersionedNodes; } private final PaginatedUpdater deviceProfileEntityDynamicConditionsUpdater = diff --git a/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java index 16a266e485..eb989ac5b6 100644 --- a/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java @@ -27,8 +27,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.test.context.ContextConfiguration; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.action.TbCreateAlarmNode; import org.thingsboard.rule.engine.action.TbCreateAlarmNodeConfiguration; +import org.thingsboard.rule.engine.api.TbVersionedNode; +import org.thingsboard.rule.engine.metadata.TbGetRelatedAttributeNode; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; @@ -128,6 +131,82 @@ public class RuleChainControllerTest extends AbstractControllerTest { ActionType.UPDATED); } + @Test + public void testSaveRuleChainMetadataWithVersionedNodes() throws Exception { + RuleChain ruleChain = new RuleChain(); + ruleChain.setName("RuleChain"); + + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + Assert.assertNotNull(savedRuleChain); + RuleChainId ruleChainId = savedRuleChain.getId(); + Assert.assertNotNull(ruleChainId); + Assert.assertTrue(savedRuleChain.getCreatedTime() > 0); + Assert.assertEquals(ruleChain.getName(), savedRuleChain.getName()); + + TbVersionedNode tbVersionedNode = new TbGetRelatedAttributeNode(); + String ruleNodeType = tbVersionedNode.getClass().getName(); + int currentVersion = tbVersionedNode.getCurrentVersion(); + + String oldConfig = "{\"attrMapping\":{\"serialNumber\":\"sn\"}," + + "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + + "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + + "\"fetchLastLevelOnly\":false},\"telemetry\":false}"; + + String newConfig = "{\"fetchTo\":\"METADATA\"," + + "\"attrMapping\":{\"serialNumber\":\"sn\"}," + + "\"dataToFetch\":\"ATTRIBUTES\"," + + "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + + "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + + "\"fetchLastLevelOnly\":false}}"; + + var ruleChainMetaData = createRuleChainMetadataWithTbVersionedNodes( + ruleChainId, + ruleNodeType, + currentVersion, + oldConfig, + newConfig + ); + var savedRuleChainMetaData = doPost("/api/ruleChain/metadata", ruleChainMetaData, RuleChainMetaData.class); + + Assert.assertEquals(ruleChainId, savedRuleChainMetaData.getRuleChainId()); + Assert.assertEquals(2, savedRuleChainMetaData.getNodes().size()); + + for (RuleNode ruleNode : savedRuleChainMetaData.getNodes()) { + Assert.assertNotNull(ruleNode.getId()); + Assert.assertEquals(currentVersion, ruleNode.getConfigurationVersion()); + Assert.assertEquals(JacksonUtil.toJsonNode(newConfig), ruleNode.getConfiguration()); + } + } + + private RuleChainMetaData createRuleChainMetadataWithTbVersionedNodes( + RuleChainId ruleChainId, + String ruleNodeType, + int currentVersion, + String oldConfig, + String newConfig + ) { + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + ruleChainMetaData.setRuleChainId(ruleChainId); + + var ruleNodeWithOldConfig = new RuleNode(); + ruleNodeWithOldConfig.setName("Old Rule Node"); + ruleNodeWithOldConfig.setType(ruleNodeType); + ruleNodeWithOldConfig.setConfiguration(JacksonUtil.toJsonNode(oldConfig)); + + var ruleNodeWithNewConfig = new RuleNode(); + ruleNodeWithNewConfig.setName("New Rule Node"); + ruleNodeWithNewConfig.setType(ruleNodeType); + ruleNodeWithNewConfig.setConfigurationVersion(currentVersion); + ruleNodeWithNewConfig.setConfiguration(JacksonUtil.toJsonNode(newConfig)); + + List ruleNodes = new ArrayList<>(); + ruleNodes.add(ruleNodeWithOldConfig); + ruleNodes.add(ruleNodeWithNewConfig); + ruleChainMetaData.setFirstNodeIndex(0); + ruleChainMetaData.setNodes(ruleNodes); + return ruleChainMetaData; + } + @Test public void testSaveRuleChainWithViolationOfLengthValidation() throws Exception { diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 601b6d333e..4cf96dfa0d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -28,7 +28,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.rule.engine.api.VersionedNode; +import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.Edge; @@ -185,17 +185,62 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } updatedRuleNodes.add(new RuleNodeUpdateResult(existingNode, newRuleNode)); } + RuleChainId ruleChainId = ruleChain.getId(); if (nodes != null) { for (RuleNode node : toAddOrUpdate) { - node.setRuleChainId(ruleChain.getId()); + node.setRuleChainId(ruleChainId); + String ruleNodeType = node.getType(); + RuleNodeId ruleNodeId = node.getId(); + try { + var ruleNodeClazz = Class.forName(ruleNodeType); + if (TbVersionedNode.class.isAssignableFrom(ruleNodeClazz)) { + TbVersionedNode tbVersionedNode = (TbVersionedNode) ruleNodeClazz.getDeclaredConstructor().newInstance(); + int fromVersion = node.getConfigurationVersion(); + int toVersion = tbVersionedNode.getCurrentVersion(); + if (fromVersion < toVersion) { + log.debug("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", + ruleNodeId, + ruleNodeType, + fromVersion, + toVersion); + try { + TbPair upgradeResult = tbVersionedNode.upgrade(fromVersion, node.getConfiguration()); + if (upgradeResult.getFirst()) { + node.setConfiguration(upgradeResult.getSecond()); + log.info("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}", + ruleNodeId, + ruleNodeType, + ruleChainId, + fromVersion, + toVersion); + } + node.setConfigurationVersion(toVersion); + } catch (TbNodeException e) { + log.warn("Failed to upgrade rule node with id: {} type: {} rule chain id: {} fromVersion: {} toVersion: {} due to: ", + ruleNodeId, + ruleNodeType, + ruleChainId, + fromVersion, + toVersion, + e); + } + } else { + log.debug("Rule node with id: {} type: {} ruleChainId: {} already set to latest version!", + ruleNodeId, + ruleChainId, + ruleNodeType); + } + } + } catch (ClassNotFoundException | + InvocationTargetException | + InstantiationException | + IllegalAccessException | + NoSuchMethodException e) { + log.error("Failed to create instance of rule node with id: {} type: {}, rule chain id: {}", ruleNodeId, ruleNodeType, ruleChainId); + } RuleNode savedNode = ruleNodeDao.save(tenantId, node); relations.add(new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); -// TbPair upgradeResult = upgradeRuleNode(savedNode); -// if (upgradeResult.getFirst()) { -// savedNode.setConfiguration(upgradeResult.getSecond()); -// savedNode = ruleNodeDao.save(tenantId, savedNode); -// } int index = nodes.indexOf(node); nodes.set(index, savedNode); ruleNodeIndexMap.put(savedNode.getId(), index); @@ -228,7 +273,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC RuleChain targetRuleChain = findRuleChainById(TenantId.SYS_TENANT_ID, targetRuleChainId); RuleNode targetNode = new RuleNode(); targetNode.setName(targetRuleChain != null ? targetRuleChain.getName() : "Rule Chain Input"); - targetNode.setRuleChainId(ruleChain.getId()); + targetNode.setRuleChainId(ruleChainId); targetNode.setType("org.thingsboard.rule.engine.flow.TbRuleChainInputNode"); var configuration = JacksonUtil.newObjectNode(); configuration.put("ruleChainId", targetRuleChainId.getId().toString()); @@ -241,7 +286,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC targetNode = ruleNodeDao.save(tenantId, targetNode); EntityRelation sourceRuleChainToRuleNode = new EntityRelation(); - sourceRuleChainToRuleNode.setFrom(ruleChain.getId()); + sourceRuleChainToRuleNode.setFrom(ruleChainId); sourceRuleChainToRuleNode.setTo(targetNode.getId()); sourceRuleChainToRuleNode.setType(EntityRelation.CONTAINS_TYPE); sourceRuleChainToRuleNode.setTypeGroup(RelationTypeGroup.RULE_CHAIN); @@ -265,40 +310,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC return RuleChainUpdateResult.successful(updatedRuleNodes); } - private TbPair upgradeRuleNode(RuleNode ruleNode) { - RuleNodeId ruleNodeId = ruleNode.getId(); - String ruleNodeType = ruleNode.getType(); - int fromVersion = ruleNode.getConfigurationVersion(); - try { - var ruleNodeClass = Class.forName(ruleNodeType).getDeclaredConstructor().newInstance(); - if (ruleNodeClass instanceof VersionedNode) { - VersionedNode versionedNode = (VersionedNode) ruleNodeClass; - int toVersion = versionedNode.getCurrentVersion(); - log.info("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", - ruleNodeId, - ruleNodeType, - fromVersion, - toVersion); - try { - return versionedNode.upgrade(ruleNodeId, fromVersion, ruleNode.getConfiguration()); - } catch (TbNodeException e) { - log.warn("Failed to upgrade rule node with id: {} fromVersion: {} toVersion: {} due to: ", - ruleNodeId, - fromVersion, - toVersion, - e); - } - } - } catch (ClassNotFoundException | - InvocationTargetException | - InstantiationException | - IllegalAccessException | - NoSuchMethodException e) { - log.warn("Failed to create instance of rule node with id: {} and type: {}", ruleNodeId, ruleNodeType); - } - return new TbPair<>(false, ruleNode.getConfiguration()); - } - @Override public RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId) { Validator.validateId(ruleChainId, "Incorrect rule chain id."); diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java similarity index 77% rename from rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java rename to rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java index 2c442588eb..ce9a63111b 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/VersionedNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java @@ -16,12 +16,11 @@ package org.thingsboard.rule.engine.api; import com.fasterxml.jackson.databind.JsonNode; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.util.TbPair; -public interface VersionedNode extends TbNode { +public interface TbVersionedNode extends TbNode { - TbPair upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException; + TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException; int getCurrentVersion(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java index ebf99765b5..924092ad87 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java @@ -22,12 +22,10 @@ import com.google.common.util.concurrent.Futures; import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.rule.engine.api.VersionedNode; +import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; @@ -36,7 +34,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; import java.util.NoSuchElementException; @Slf4j -public abstract class TbAbstractNodeWithFetchTo implements VersionedNode { +public abstract class TbAbstractNodeWithFetchTo implements TbVersionedNode { protected final static String FETCH_TO_PROPERTY_NAME = "fetchTo"; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java index 2d9804b8d8..ec21706ff1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java @@ -25,7 +25,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.util.TbPair; @@ -89,7 +88,7 @@ public class TbFetchDeviceCredentialsNode extends TbAbstractNodeWithFetchTo upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index 8281db6a26..2d1f02acf8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -25,7 +25,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; @@ -57,7 +56,7 @@ public class TbGetAttributesNode extends TbAbstractGetAttributesNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index eaf197c6a5..f9cbba2ffd 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -27,7 +27,6 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesCustomerIdAsyncLoader; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -72,7 +71,7 @@ public class TbGetCustomerAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index aff1f3b00e..c31f9cbcef 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -33,7 +33,6 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -107,7 +106,7 @@ public class TbGetCustomerDetailsNode extends TbAbstractGetEntityDetailsNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java index d47f8445b4..d671a61536 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNode.java @@ -26,7 +26,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesRelatedDeviceIdAsyncLoader; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; @@ -60,7 +59,7 @@ public class TbGetDeviceAttrNode extends TbAbstractGetAttributesNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java index 4b1f5e1b07..79d9a982c2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java @@ -28,7 +28,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; @@ -102,7 +101,7 @@ public class TbGetOriginatorFieldsNode extends TbAbstractNodeWithFetchTo upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) { if (fromVersion == 0) { var newConfigObjectNode = (ObjectNode) oldConfiguration; newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, FetchTo.METADATA.name()); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index 3193dee09d..c89d7c4b59 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -26,7 +26,6 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesRelatedEntityIdAsyncLoader; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -75,7 +74,7 @@ public class TbGetRelatedAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index 4ae7b1d3a4..8ff44e297c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -25,7 +25,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -66,7 +65,7 @@ public class TbGetTenantAttributeNode extends TbAbstractGetEntityAttrNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeToUseFetchToAndDataToFetch(oldConfiguration) : new TbPair<>(false, oldConfiguration); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java index 9d934121b8..759a91785c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNode.java @@ -24,7 +24,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; @@ -62,7 +61,7 @@ public class TbGetTenantDetailsNode extends TbAbstractGetEntityDetailsNode upgrade(RuleNodeId ruleNodeId, int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { return fromVersion == 0 ? upgradeRuleNodesWithOldPropertyToUseFetchTo( oldConfiguration, diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java index 0c589df01c..353317a1a3 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNodeTest.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,6 +32,7 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.TbMsgCallback; @@ -40,6 +42,8 @@ import java.util.Map; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.willAnswer; import static org.mockito.Mockito.doAnswer; @@ -67,7 +71,6 @@ public class TbFetchDeviceCredentialsNodeTest { void setUp() throws TbNodeException { deviceId = new DeviceId(UUID.randomUUID()); config = new TbFetchDeviceCredentialsNodeConfiguration().defaultConfiguration(); - config.setFetchTo(FetchTo.METADATA); node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config))); } @@ -150,6 +153,15 @@ public class TbFetchDeviceCredentialsNodeTest { assertThat(exceptionCaptor.getValue()).isInstanceOf(RuntimeException.class); } + @Test + void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + String oldConfig = "{\"fetchToMetadata\":true}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + assertTrue(upgrade.getFirst()); + assertEquals(JacksonUtil.valueToTree(config), upgrade.getSecond()); + } + private TbMsg getTbMsg(EntityId entityId) { final Map mdMap = Map.of( "country", "US", diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java index b627b8e5f8..52f11cd4a8 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java @@ -16,10 +16,12 @@ package org.thingsboard.rule.engine.metadata; import com.datastax.oss.driver.api.core.uuid.Uuids; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -39,6 +41,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.attributes.AttributesService; @@ -247,6 +250,23 @@ public class TbGetAttributesNodeTest { assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetAttributesNodeConfiguration().defaultConfiguration(); + var node = new TbGetAttributesNode(); + String oldConfig = "{\"fetchToData\":false," + + "\"clientAttributeNames\":[]," + + "\"sharedAttributeNames\":[]," + + "\"serverAttributeNames\":[]," + + "\"latestTsKeyNames\":[]," + + "\"tellFailureIfAbsent\":true," + + "\"getLatestValueWithTs\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private TbMsg checkMsg(boolean checkSuccess) { var msgCaptor = ArgumentCaptor.forClass(TbMsg.class); if (checkSuccess) { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java index bc1ba87322..201992e949 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java @@ -15,10 +15,12 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -46,6 +48,7 @@ import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.asset.AssetService; @@ -451,6 +454,17 @@ public class TbGetCustomerAttributeNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetaData); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + var node = new TbGetCustomerAttributeNode(); + String oldConfig = "{\"attrMapping\":{\"alarmThreshold\":\"threshold\"},\"telemetry\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, DataToFetch dataToFetch, EntityId originator) { config.setAttrMapping(Map.of( "sourceKey1", "targetKey1", diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java index fc61b0d2b7..901172d344 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNodeTest.java @@ -15,9 +15,11 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -44,6 +46,7 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.asset.AssetService; @@ -444,6 +447,17 @@ public class TbGetCustomerDetailsNodeTest { assertThat(actualException.getMessage()).isEqualTo("Entity with entityType 'DASHBOARD' is not supported."); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetCustomerDetailsNodeConfiguration().defaultConfiguration(); + var node = new TbGetCustomerDetailsNode(); + String oldConfig = "{\"detailsList\":[],\"addToMetadata\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, List detailsList, EntityId originator) { config.setDetailsList(detailsList); config.setFetchTo(fetchTo); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java new file mode 100644 index 0000000000..c7d5e1c0c3 --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.util.TbPair; + +public class TbGetDeviceAttrNodeTest { + + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetDeviceAttrNodeConfiguration().defaultConfiguration(); + var node = new TbGetDeviceAttrNode(); + String oldConfig = "{\"fetchToData\":false," + + "\"clientAttributeNames\":[]," + + "\"sharedAttributeNames\":[]," + + "\"serverAttributeNames\":[]," + + "\"latestTsKeyNames\":[]," + + "\"tellFailureIfAbsent\":true," + + "\"getLatestValueWithTs\":false," + + "\"deviceRelationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1,\"relationType\":\"Contains\",\"deviceTypes\":[\"default\"]," + + "\"fetchLastLevelOnly\":false}}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + +} \ No newline at end of file diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java index 7743fda2be..6b162d08fb 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java @@ -15,9 +15,11 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -33,6 +35,7 @@ import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.device.DeviceService; @@ -339,4 +342,15 @@ public class TbGetOriginatorFieldsNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(msgMetaData); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetOriginatorFieldsConfiguration().defaultConfiguration(); + var node = new TbGetOriginatorFieldsNode(); + String oldConfig = "{\"fieldsMapping\":{\"name\":\"originatorName\",\"type\":\"originatorType\"},\"ignoreNullStrings\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index f5684d1786..a9a04fb3df 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -15,10 +15,12 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -43,6 +45,7 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.session.SessionMsgType; @@ -548,6 +551,21 @@ public class TbGetRelatedAttributeNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetadata); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetRelatedAttrNodeConfiguration().defaultConfiguration(); + var node = new TbGetRelatedAttributeNode(); + String oldConfig = "{\"attrMapping\":{\"serialNumber\":\"sn\"}," + + "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + + "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + + "\"fetchLastLevelOnly\":false}," + + "\"telemetry\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, DataToFetch dataToFetch, EntityId originator) { config.setDataToFetch(dataToFetch); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index 19641b7000..5c56561a48 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -15,10 +15,12 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -41,6 +43,7 @@ import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.attributes.AttributesService; @@ -381,6 +384,17 @@ public class TbGetTenantAttributeNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(expectedMsgMetaData); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + var node = new TbGetTenantAttributeNode(); + String oldConfig = "{\"attrMapping\":{\"alarmThreshold\":\"threshold\"},\"telemetry\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, DataToFetch dataToFetch, EntityId originator) { config.setAttrMapping(Map.of( "sourceKey1", "targetKey1", diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java index e5333cb459..87e933f5bd 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantDetailsNodeTest.java @@ -15,7 +15,9 @@ */ package org.thingsboard.rule.engine.metadata; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -30,6 +32,7 @@ import org.thingsboard.rule.engine.util.ContactBasedEntityDetails; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.tenant.TenantService; @@ -259,6 +262,17 @@ public class TbGetTenantDetailsNodeTest { assertThat(actualMessageCaptor.getValue().getMetaData()).isEqualTo(msg.getMetaData()); } + @Test + public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { + var defaultConfig = new TbGetTenantDetailsNodeConfiguration().defaultConfiguration(); + var node = new TbGetTenantDetailsNode(); + String oldConfig = "{\"detailsList\":[],\"addToMetadata\":false}"; + JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); + TbPair upgrade = node.upgrade(0, configJson); + Assertions.assertTrue(upgrade.getFirst()); + Assertions.assertEquals(JacksonUtil.valueToTree(defaultConfig), upgrade.getSecond()); + } + private void prepareMsgAndConfig(FetchTo fetchTo, List detailsList) { config.setDetailsList(detailsList); config.setFetchTo(fetchTo); diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts index 7fff22a12a..a06c06ba36 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts @@ -555,6 +555,7 @@ export class RuleChainPageComponent extends PageComponent ruleNodeId: ruleNode.id, additionalInfo: ruleNode.additionalInfo, configuration: ruleNode.configuration, + configurationVersion: ruleNode.configurationVersion, debugMode: ruleNode.debugMode, singletonMode: ruleNode.singletonMode, x: Math.round(ruleNode.additionalInfo.layoutX), @@ -1424,6 +1425,7 @@ export class RuleChainPageComponent extends PageComponent id: node.ruleNodeId, type: node.component.clazz, name: node.name, + configurationVersion: node.configurationVersion, configuration: node.configuration, additionalInfo: node.additionalInfo ? node.additionalInfo : {}, debugMode: node.debugMode, diff --git a/ui-ngx/src/app/shared/models/rule-node.models.ts b/ui-ngx/src/app/shared/models/rule-node.models.ts index dbb065f7f2..19d4a24a9d 100644 --- a/ui-ngx/src/app/shared/models/rule-node.models.ts +++ b/ui-ngx/src/app/shared/models/rule-node.models.ts @@ -37,6 +37,7 @@ export interface RuleNode extends BaseData { name: string; debugMode: boolean; singletonMode: boolean; + configurationVersion?: number; configuration: RuleNodeConfiguration; additionalInfo?: any; } From 2c251e2f5cc75fd0126c068a3a543fd5ebaf2184 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 19 May 2023 13:58:53 +0300 Subject: [PATCH 065/207] remove duplicate logic for TbGetOriginatorFieldsNode and TbRelatedAttributesNode && fix typos --- .../update/DefaultDataUpdateService.java | 9 +- .../server/dao/rule/BaseRuleChainService.java | 20 +- .../CassandraBaseTimeseriesLatestDao.java | 2 +- .../metadata/TbAbstractGetEntityAttrNode.java | 171 ------------------ .../metadata/TbAbstractGetEntityDataNode.java | 89 +++++++++ .../metadata/TbAbstractGetMappedDataNode.java | 153 ++++++++++++++++ .../metadata/TbGetCustomerAttributeNode.java | 10 +- ... => TbGetEntityDataNodeConfiguration.java} | 14 +- .../TbGetMappedDataNodeConfiguration.java | 29 +++ .../TbGetOriginatorFieldsConfiguration.java | 12 +- .../metadata/TbGetOriginatorFieldsNode.java | 65 ++----- .../metadata/TbGetRelatedAttributeNode.java | 12 +- ...=> TbGetRelatedDataNodeConfiguration.java} | 12 +- .../metadata/TbGetTenantAttributeNode.java | 10 +- .../TbGetCustomerAttributeNodeTest.java | 16 +- .../TbGetOriginatorFieldsNodeTest.java | 25 +-- .../TbGetRelatedAttributeNodeTest.java | 45 +++-- .../TbGetTenantAttributeNodeTest.java | 16 +- 18 files changed, 396 insertions(+), 314 deletions(-) delete mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDataNode.java create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetMappedDataNode.java rename rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/{TbGetEntityAttrNodeConfiguration.java => TbGetEntityDataNodeConfiguration.java} (67%) create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetMappedDataNodeConfiguration.java rename rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/{TbGetRelatedAttrNodeConfiguration.java => TbGetRelatedDataNodeConfiguration.java} (82%) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index c896e10dc3..31988394ab 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -277,6 +277,7 @@ public class DefaultDataUpdateService implements DataUpdateService { log.error("Unexpected error during rule nodes upgrade: ", e); } } + private ArrayList getTbVersionedNodes() { var ruleNodeDefinitions = beanDiscoveryService.discoverBeansByAnnotationType( org.thingsboard.rule.engine.api.RuleNode.class diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 4cf96dfa0d..8c25a97298 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -207,14 +207,14 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC TbPair upgradeResult = tbVersionedNode.upgrade(fromVersion, node.getConfiguration()); if (upgradeResult.getFirst()) { node.setConfiguration(upgradeResult.getSecond()); - log.info("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}", - ruleNodeId, - ruleNodeType, - ruleChainId, - fromVersion, - toVersion); } node.setConfigurationVersion(toVersion); + log.debug("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}", + ruleNodeId, + ruleNodeType, + ruleChainId, + fromVersion, + toVersion); } catch (TbNodeException e) { log.warn("Failed to upgrade rule node with id: {} type: {} rule chain id: {} fromVersion: {} toVersion: {} due to: ", ruleNodeId, diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesLatestDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesLatestDao.java index 6c093509d0..605e0bb428 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesLatestDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesLatestDao.java @@ -75,7 +75,7 @@ public class CassandraBaseTimeseriesLatestDao extends AbstractCassandraBaseTimes try { return findLatest(tenantId, entityId, key, rs -> convertResultToTsKvEntry(key, rs.one())).get(); } catch (InterruptedException | ExecutionException e) { - log.error("[{}][{}] Failed to get latest entry for key: {}", tenantId, entityId, key, e); + log.error("[{}][{}] Failed to get latest entry for key: {} due to: ", tenantId, entityId, key, e); throw new RuntimeException(e); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java deleted file mode 100644 index 19127ac5bf..0000000000 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityAttrNode.java +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.rule.engine.metadata; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; -import lombok.extern.slf4j.Slf4j; -import org.thingsboard.rule.engine.api.TbContext; -import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.rule.engine.api.util.TbNodeUtils; -import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; -import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.RuleNodeId; -import org.thingsboard.server.common.data.kv.KvEntry; -import org.thingsboard.server.common.data.util.TbPair; -import org.thingsboard.server.common.msg.TbMsg; -import org.thingsboard.server.common.msg.TbMsgMetaData; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static org.thingsboard.common.util.DonAsynchron.withCallback; -import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; - -@Slf4j -public abstract class TbAbstractGetEntityAttrNode extends TbAbstractNodeWithFetchTo { - - protected final static String DATA_TO_FETCH_PROPERTY_NAME = "dataToFetch"; - protected static final String OLD_PROPERTY_NAME = "telemetry"; - - @Override - public void onMsg(TbContext ctx, TbMsg msg) { - var msgDataAsObjectNode = FetchTo.DATA.equals(fetchTo) ? getMsgDataAsObjectNode(msg) : null; - withCallback(findEntityAsync(ctx, msg.getOriginator()), - entityId -> getData(ctx, msg, entityId, msgDataAsObjectNode), - t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); - } - - protected abstract ListenableFuture findEntityAsync(TbContext ctx, EntityId originator); - - protected void checkIfMappingIsNotEmptyOrElseThrow(Map attrMapping) throws TbNodeException { - if (attrMapping == null || attrMapping.isEmpty()) { - throw new TbNodeException("At least one mapping entry should be specified!"); - } - } - - protected abstract void checkDataToFetchSupportedOrElseThrow(DataToFetch dataToFetch) throws TbNodeException; - - private void getData(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) { - var mappingsMap = new HashMap(); - if (DataToFetch.FIELDS.equals(config.getDataToFetch())) { - config.getAttrMapping().forEach((sourceField, targetKey) -> { - String patternProcessedTargetKey = TbNodeUtils.processPattern(targetKey, msg); - mappingsMap.put(sourceField, patternProcessedTargetKey); - }); - withCallback(collectMappedEntityFieldsAsync(ctx, entityId, mappingsMap), - targetKeysToSourceValuesMap -> { - TbMsgMetaData msgMetaData = msg.getMetaData().copy(); - for (var entry : targetKeysToSourceValuesMap.entrySet()) { - var targetKeyName = entry.getKey(); - var sourceFieldValue = entry.getValue(); - if (FetchTo.DATA.equals(fetchTo)) { - msgDataAsJsonNode.put(targetKeyName, sourceFieldValue); - } else if (FetchTo.METADATA.equals(fetchTo)) { - msgMetaData.putValue(targetKeyName, sourceFieldValue); - } - } - TbMsg outMsg = transformMessage(msg, msgDataAsJsonNode, msgMetaData); - ctx.tellSuccess(outMsg); - }, - t -> ctx.tellFailure(msg, t), - MoreExecutors.directExecutor()); - } else { - config.getAttrMapping().forEach((sourceKey, targetKey) -> { - String patternProcessedSourceKey = TbNodeUtils.processPattern(sourceKey, msg); - String patternProcessedTargetKey = TbNodeUtils.processPattern(targetKey, msg); - mappingsMap.put(patternProcessedSourceKey, patternProcessedTargetKey); - }); - var sourceKeys = List.copyOf(mappingsMap.keySet()); - withCallback(DataToFetch.LATEST_TELEMETRY.equals(config.getDataToFetch()) ? - getLatestTelemetryAsync(ctx, entityId, sourceKeys) : - getAttributesAsync(ctx, entityId, sourceKeys), - data -> putDataAndTell(ctx, msg, data, mappingsMap, msgDataAsJsonNode), - t -> ctx.tellFailure(msg, t), - MoreExecutors.directExecutor()); - } - - } - - private ListenableFuture> collectMappedEntityFieldsAsync(TbContext ctx, EntityId entityId, HashMap mappingsMap) { - return Futures.transform(EntitiesFieldsAsyncLoader.findAsync(ctx, entityId), - fieldsData -> { - var targetKeysToSourceValuesMap = new HashMap(); - for (var mappingEntry : mappingsMap.entrySet()) { - var sourceFieldName = mappingEntry.getKey(); - var targetKeyName = mappingEntry.getValue(); - var sourceFieldValue = fieldsData.getFieldValue(sourceFieldName, true); - if (sourceFieldValue != null) { - targetKeysToSourceValuesMap.put(targetKeyName, sourceFieldValue); - } - } - return targetKeysToSourceValuesMap; - }, ctx.getDbCallbackExecutor() - ); - } - - private ListenableFuture> getAttributesAsync(TbContext ctx, EntityId entityId, List attrKeys) { - var latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, attrKeys); - return Futures.transform(latest, l -> - l.stream() - .map(i -> (KvEntry) i) - .collect(Collectors.toList()), - ctx.getDbCallbackExecutor()); - } - - private ListenableFuture> getLatestTelemetryAsync(TbContext ctx, EntityId entityId, List timeseriesKeys) { - var latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, timeseriesKeys); - return Futures.transform(latest, l -> - l.stream() - .map(i -> (KvEntry) i) - .collect(Collectors.toList()), - ctx.getDbCallbackExecutor()); - } - - private void putDataAndTell(TbContext ctx, TbMsg msg, List data, Map map, ObjectNode msgData) { - var msgMetaData = msg.getMetaData().copy(); - for (KvEntry entry : data) { - String targetKey = map.get(entry.getKey()); - enrichMessage(msgData, msgMetaData, entry, targetKey); - } - ctx.tellSuccess(transformMessage(msg, msgData, msgMetaData)); - } - - protected TbPair upgradeToUseFetchToAndDataToFetch(JsonNode oldConfiguration) throws TbNodeException { - var newConfigObjectNode = (ObjectNode) oldConfiguration; - if (!newConfigObjectNode.has(OLD_PROPERTY_NAME)) { - throw new TbNodeException("property to update: '" + OLD_PROPERTY_NAME + "' doesn't exists in configuration!"); - } - var value = newConfigObjectNode.get(OLD_PROPERTY_NAME).asText(); - if ("true".equals(value)) { - newConfigObjectNode.remove(OLD_PROPERTY_NAME); - newConfigObjectNode.put(DATA_TO_FETCH_PROPERTY_NAME, DataToFetch.LATEST_TELEMETRY.name()); - } else if ("false".equals(value)) { - newConfigObjectNode.remove(OLD_PROPERTY_NAME); - newConfigObjectNode.put(DATA_TO_FETCH_PROPERTY_NAME, DataToFetch.ATTRIBUTES.name()); - } else { - throw new TbNodeException("property to update: '" + OLD_PROPERTY_NAME + "' has unexpected value: " + value + ". Allowed values: true or false!"); - } - newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, FetchTo.METADATA.name()); - return new TbPair<>(true, newConfigObjectNode); - } - -} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDataNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDataNode.java new file mode 100644 index 0000000000..5615147fd0 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetEntityDataNode.java @@ -0,0 +1,89 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.util.concurrent.ListenableFuture; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.util.TbPair; +import org.thingsboard.server.common.msg.TbMsg; + +import static org.thingsboard.common.util.DonAsynchron.withCallback; + +@Slf4j +public abstract class TbAbstractGetEntityDataNode extends TbAbstractGetMappedDataNode { + + protected final static String DATA_TO_FETCH_PROPERTY_NAME = "dataToFetch"; + protected static final String OLD_DATA_TO_FETCH_PROPERTY_NAME = "telemetry"; + protected final static String DATA_MAPPING_PROPERTY_NAME = "dataMapping"; + protected static final String OLD_DATA_MAPPING_PROPERTY_NAME = "attrMapping"; + + @Override + public void onMsg(TbContext ctx, TbMsg msg) { + var msgDataAsObjectNode = FetchTo.DATA.equals(fetchTo) ? getMsgDataAsObjectNode(msg) : null; + withCallback(findEntityAsync(ctx, msg.getOriginator()), + entityId -> processDataAndTell(ctx, msg, entityId, msgDataAsObjectNode), + t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); + } + + protected abstract ListenableFuture findEntityAsync(TbContext ctx, EntityId originator); + + protected abstract void checkDataToFetchSupportedOrElseThrow(DataToFetch dataToFetch) throws TbNodeException; + + protected void processDataAndTell(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) { + DataToFetch dataToFetch = config.getDataToFetch(); + switch (dataToFetch) { + case ATTRIBUTES: + processAttributesKvEntryData(ctx, msg, entityId, msgDataAsJsonNode); + break; + case LATEST_TELEMETRY: + processTsKvEntryData(ctx, msg, entityId, msgDataAsJsonNode); + break; + case FIELDS: + processFieldsData(ctx, msg, entityId, msgDataAsJsonNode, true); + break; + } + } + + protected TbPair upgradeToUseFetchToAndDataToFetch(JsonNode oldConfiguration) throws TbNodeException { + var newConfigObjectNode = (ObjectNode) oldConfiguration; + if (!newConfigObjectNode.has(OLD_DATA_TO_FETCH_PROPERTY_NAME)) { + throw new TbNodeException("property to update: '" + OLD_DATA_TO_FETCH_PROPERTY_NAME + "' doesn't exists in configuration!"); + } + if (!newConfigObjectNode.has(OLD_DATA_MAPPING_PROPERTY_NAME)) { + throw new TbNodeException("property to update: '" + OLD_DATA_MAPPING_PROPERTY_NAME + "' doesn't exists in configuration!"); + } + newConfigObjectNode.set(DATA_MAPPING_PROPERTY_NAME, newConfigObjectNode.get(OLD_DATA_MAPPING_PROPERTY_NAME)); + newConfigObjectNode.remove(OLD_DATA_MAPPING_PROPERTY_NAME); + var value = newConfigObjectNode.get(OLD_DATA_TO_FETCH_PROPERTY_NAME).asText(); + if ("true".equals(value)) { + newConfigObjectNode.remove(OLD_DATA_TO_FETCH_PROPERTY_NAME); + newConfigObjectNode.put(DATA_TO_FETCH_PROPERTY_NAME, DataToFetch.LATEST_TELEMETRY.name()); + } else if ("false".equals(value)) { + newConfigObjectNode.remove(OLD_DATA_TO_FETCH_PROPERTY_NAME); + newConfigObjectNode.put(DATA_TO_FETCH_PROPERTY_NAME, DataToFetch.ATTRIBUTES.name()); + } else { + throw new TbNodeException("property to update: '" + OLD_DATA_TO_FETCH_PROPERTY_NAME + "' has unexpected value: " + value + ". Allowed values: true or false!"); + } + newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, FetchTo.METADATA.name()); + return new TbPair<>(true, newConfigObjectNode); + } + +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetMappedDataNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetMappedDataNode.java new file mode 100644 index 0000000000..b4e4d29524 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetMappedDataNode.java @@ -0,0 +1,153 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.rule.engine.api.util.TbNodeUtils; +import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.kv.KvEntry; +import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgMetaData; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.thingsboard.common.util.DonAsynchron.withCallback; +import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; + +@Slf4j +public abstract class TbAbstractGetMappedDataNode extends TbAbstractNodeWithFetchTo { + + protected void checkIfMappingIsNotEmptyOrElseThrow(Map dataMapping) throws TbNodeException { + if (dataMapping == null || dataMapping.isEmpty()) { + throw new TbNodeException("At least one mapping entry should be specified!"); + } + } + + protected void processFieldsData(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode, boolean ignoreNullStrings) { + var mappingsMap = processFieldsMappingPatterns(msg); + withCallback(getEntityFieldsAsync(ctx, entityId, mappingsMap, ignoreNullStrings), + data -> putFieldsDataAndTell(ctx, msg, msgDataAsJsonNode, data), + t -> ctx.tellFailure(msg, t), + MoreExecutors.directExecutor()); + } + + protected void processAttributesKvEntryData(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) { + var mappingsMap = processKvEntryMappingPatterns(msg); + var sourceKeys = List.copyOf(mappingsMap.keySet()); + withCallback(getAttributesAsync(ctx, entityId, sourceKeys), + data -> putKvEntryDataAndTell(ctx, msg, data, mappingsMap, msgDataAsJsonNode), + t -> ctx.tellFailure(msg, t), + MoreExecutors.directExecutor()); + } + + protected void processTsKvEntryData(TbContext ctx, TbMsg msg, T entityId, ObjectNode msgDataAsJsonNode) { + var mappingsMap = processKvEntryMappingPatterns(msg); + var sourceKeys = List.copyOf(mappingsMap.keySet()); + withCallback(getLatestTelemetryAsync(ctx, entityId, sourceKeys), + data -> putKvEntryDataAndTell(ctx, msg, data, mappingsMap, msgDataAsJsonNode), + t -> ctx.tellFailure(msg, t), + MoreExecutors.directExecutor()); + } + + private void putFieldsDataAndTell(TbContext ctx, TbMsg msg, ObjectNode msgDataAsJsonNode, Map targetKeysToSourceValuesMap) { + TbMsgMetaData msgMetaData = msg.getMetaData().copy(); + for (var entry : targetKeysToSourceValuesMap.entrySet()) { + var targetKeyName = entry.getKey(); + var sourceFieldValue = entry.getValue(); + if (FetchTo.DATA.equals(fetchTo)) { + msgDataAsJsonNode.put(targetKeyName, sourceFieldValue); + } else if (FetchTo.METADATA.equals(fetchTo)) { + msgMetaData.putValue(targetKeyName, sourceFieldValue); + } + } + TbMsg outMsg = transformMessage(msg, msgDataAsJsonNode, msgMetaData); + ctx.tellSuccess(outMsg); + } + + private void putKvEntryDataAndTell(TbContext ctx, TbMsg msg, List data, Map map, ObjectNode msgData) { + var msgMetaData = msg.getMetaData().copy(); + for (KvEntry entry : data) { + String targetKey = map.get(entry.getKey()); + enrichMessage(msgData, msgMetaData, entry, targetKey); + } + ctx.tellSuccess(transformMessage(msg, msgData, msgMetaData)); + } + + private Map processFieldsMappingPatterns(TbMsg msg) { + var mappingsMap = new HashMap(); + config.getDataMapping().forEach((sourceField, targetKey) -> { + String patternProcessedTargetKey = TbNodeUtils.processPattern(targetKey, msg); + mappingsMap.put(sourceField, patternProcessedTargetKey); + }); + return mappingsMap; + } + + private Map processKvEntryMappingPatterns(TbMsg msg) { + var mappingsMap = new HashMap(); + config.getDataMapping().forEach((sourceKey, targetKey) -> { + String patternProcessedSourceKey = TbNodeUtils.processPattern(sourceKey, msg); + String patternProcessedTargetKey = TbNodeUtils.processPattern(targetKey, msg); + mappingsMap.put(patternProcessedSourceKey, patternProcessedTargetKey); + }); + return mappingsMap; + } + + private ListenableFuture> getEntityFieldsAsync(TbContext ctx, EntityId entityId, Map mappingsMap, boolean ignoreNullStrings) { + return Futures.transform(EntitiesFieldsAsyncLoader.findAsync(ctx, entityId), + fieldsData -> { + var targetKeysToSourceValuesMap = new HashMap(); + for (var mappingEntry : mappingsMap.entrySet()) { + var sourceFieldName = mappingEntry.getKey(); + var targetKeyName = mappingEntry.getValue(); + var sourceFieldValue = fieldsData.getFieldValue(sourceFieldName, ignoreNullStrings); + if (sourceFieldValue != null) { + targetKeysToSourceValuesMap.put(targetKeyName, sourceFieldValue); + } + } + return targetKeysToSourceValuesMap; + }, ctx.getDbCallbackExecutor() + ); + } + + private ListenableFuture> getAttributesAsync(TbContext ctx, EntityId entityId, List attrKeys) { + var latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, attrKeys); + return Futures.transform(latest, l -> + l.stream() + .map(i -> (KvEntry) i) + .collect(Collectors.toList()), + ctx.getDbCallbackExecutor()); + } + + private ListenableFuture> getLatestTelemetryAsync(TbContext ctx, EntityId entityId, List timeseriesKeys) { + var latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, timeseriesKeys); + return Futures.transform(latest, l -> + l.stream() + .map(i -> (KvEntry) i) + .collect(Collectors.toList()), + ctx.getDbCallbackExecutor()); + } + +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index f9cbba2ffd..e693dab684 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -34,7 +34,7 @@ import org.thingsboard.server.common.data.util.TbPair; @RuleNode( type = ComponentType.ENRICHMENT, name = "customer attributes", - configClazz = TbGetEntityAttrNodeConfiguration.class, + configClazz = TbGetEntityDataNodeConfiguration.class, nodeDescription = "Add Originators Customer Attributes or Latest Telemetry into Message or Metadata", nodeDetails = "Enrich the Message or Metadata with the corresponding customer's latest attributes or telemetry value. " + "The customer is selected based on the originator of the message: device, asset, etc. " + @@ -42,14 +42,14 @@ import org.thingsboard.server.common.data.util.TbPair; "Useful when you store some parameters on the customer level and would like to use them for message processing.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeCustomerAttributesConfig") -public class TbGetCustomerAttributeNode extends TbAbstractGetEntityAttrNode { +public class TbGetCustomerAttributeNode extends TbAbstractGetEntityDataNode { private static final String CUSTOMER_NOT_FOUND_MESSAGE = "Failed to find customer for entity with id %s and type %s"; @Override - protected TbGetEntityAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - var config = TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); - checkIfMappingIsNotEmptyOrElseThrow(config.getAttrMapping()); + protected TbGetEntityDataNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + var config = TbNodeUtils.convert(configuration, TbGetEntityDataNodeConfiguration.class); + checkIfMappingIsNotEmptyOrElseThrow(config.getDataMapping()); checkDataToFetchSupportedOrElseThrow(config.getDataToFetch()); return config; } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityDataNodeConfiguration.java similarity index 67% rename from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java rename to rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityDataNodeConfiguration.java index eec7b497e1..eb3f3b805c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetEntityDataNodeConfiguration.java @@ -20,21 +20,19 @@ import lombok.EqualsAndHashCode; import org.thingsboard.rule.engine.api.NodeConfiguration; import java.util.HashMap; -import java.util.Map; @Data @EqualsAndHashCode(callSuper = true) -public class TbGetEntityAttrNodeConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { +public class TbGetEntityDataNodeConfiguration extends TbGetMappedDataNodeConfiguration implements NodeConfiguration { - private Map attrMapping; private DataToFetch dataToFetch; @Override - public TbGetEntityAttrNodeConfiguration defaultConfiguration() { - var configuration = new TbGetEntityAttrNodeConfiguration(); - var attrMapping = new HashMap(); - attrMapping.putIfAbsent("alarmThreshold", "threshold"); - configuration.setAttrMapping(attrMapping); + public TbGetEntityDataNodeConfiguration defaultConfiguration() { + var configuration = new TbGetEntityDataNodeConfiguration(); + var dataMapping = new HashMap(); + dataMapping.putIfAbsent("alarmThreshold", "threshold"); + configuration.setDataMapping(dataMapping); configuration.setDataToFetch(DataToFetch.ATTRIBUTES); configuration.setFetchTo(FetchTo.METADATA); return configuration; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetMappedDataNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetMappedDataNodeConfiguration.java new file mode 100644 index 0000000000..68b8f0ff31 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetMappedDataNodeConfiguration.java @@ -0,0 +1,29 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.metadata; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Map; + +@Data +@EqualsAndHashCode(callSuper = true) +public abstract class TbGetMappedDataNodeConfiguration extends TbAbstractFetchToNodeConfiguration { + + private Map dataMapping; + +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java index e5d428100b..45ca8e19c0 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsConfiguration.java @@ -24,18 +24,18 @@ import java.util.Map; @Data @EqualsAndHashCode(callSuper = true) -public class TbGetOriginatorFieldsConfiguration extends TbAbstractFetchToNodeConfiguration implements NodeConfiguration { +public class TbGetOriginatorFieldsConfiguration extends TbGetMappedDataNodeConfiguration implements NodeConfiguration { - private Map fieldsMapping; + private Map dataMapping; private boolean ignoreNullStrings; @Override public TbGetOriginatorFieldsConfiguration defaultConfiguration() { var configuration = new TbGetOriginatorFieldsConfiguration(); - var fieldsMapping = new HashMap(); - fieldsMapping.put("name", "originatorName"); - fieldsMapping.put("type", "originatorType"); - configuration.setFieldsMapping(fieldsMapping); + var dataMapping = new HashMap(); + dataMapping.put("name", "originatorName"); + dataMapping.put("type", "originatorType"); + configuration.setDataMapping(dataMapping); configuration.setIgnoreNullStrings(false); configuration.setFetchTo(FetchTo.METADATA); return configuration; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java index 79d9a982c2..f777d98bcb 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNode.java @@ -17,26 +17,18 @@ package org.thingsboard.rule.engine.metadata; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; -import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; -import org.thingsboard.server.common.msg.TbMsgMetaData; -import java.util.HashMap; -import java.util.Map; - -import static org.thingsboard.common.util.DonAsynchron.withCallback; +import java.util.concurrent.ExecutionException; /** * Created by ashvayka on 19.01.18. @@ -50,60 +42,33 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; "This node supports only following originator types: TENANT, CUSTOMER, USER, ASSET, DEVICE, ALARM, RULE_CHAIN, ENTITY_VIEW.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeOriginatorFieldsConfig") -public class TbGetOriginatorFieldsNode extends TbAbstractNodeWithFetchTo { +public class TbGetOriginatorFieldsNode extends TbAbstractGetMappedDataNode { + + protected final static String DATA_MAPPING_PROPERTY_NAME = "dataMapping"; + protected static final String OLD_DATA_MAPPING_PROPERTY_NAME = "fieldsMapping"; @Override protected TbGetOriginatorFieldsConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { var config = TbNodeUtils.convert(configuration, TbGetOriginatorFieldsConfiguration.class); - if (config.getFieldsMapping() == null || config.getFieldsMapping().isEmpty()) { - throw new TbNodeException("At least one mapping entry should be specified!"); - } + checkIfMappingIsNotEmptyOrElseThrow(config.getDataMapping()); return config; } @Override - public void onMsg(TbContext ctx, TbMsg msg) { - var msgDataAsObjectNode = FetchTo.DATA.equals(fetchTo) ? getMsgDataAsObjectNode(msg) : null; - withCallback(collectMappedEntityFieldsAsync(ctx, msg.getOriginator()), - targetKeysToSourceValuesMap -> { - TbMsgMetaData msgMetaData = msg.getMetaData().copy(); - for (var entry : targetKeysToSourceValuesMap.entrySet()) { - var targetKeyName = entry.getKey(); - var sourceFieldValue = entry.getValue(); - if (FetchTo.DATA.equals(fetchTo)) { - msgDataAsObjectNode.put(targetKeyName, sourceFieldValue); - } else if (FetchTo.METADATA.equals(fetchTo)) { - msgMetaData.putValue(targetKeyName, sourceFieldValue); - } - } - TbMsg outMsg = transformMessage(msg, msgDataAsObjectNode, msgMetaData); - ctx.tellSuccess(outMsg); - }, - t -> ctx.tellFailure(msg, t), - MoreExecutors.directExecutor()); - } - - private ListenableFuture> collectMappedEntityFieldsAsync(TbContext ctx, EntityId entityId) { - return Futures.transform(EntitiesFieldsAsyncLoader.findAsync(ctx, entityId), - fieldsData -> { - var targetKeysToSourceValuesMap = new HashMap(); - for (var mappingEntry : config.getFieldsMapping().entrySet()) { - var sourceFieldName = mappingEntry.getKey(); - var targetKeyName = mappingEntry.getValue(); - var sourceFieldValue = fieldsData.getFieldValue(sourceFieldName, config.isIgnoreNullStrings()); - if (sourceFieldValue != null) { - targetKeysToSourceValuesMap.put(targetKeyName, sourceFieldValue); - } - } - return targetKeysToSourceValuesMap; - }, ctx.getDbCallbackExecutor() - ); + public void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException { + var msgDataAsJsonNode = FetchTo.DATA.equals(fetchTo) ? getMsgDataAsObjectNode(msg) : null; + processFieldsData(ctx, msg, msg.getOriginator(), msgDataAsJsonNode, config.isIgnoreNullStrings()); } @Override - public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) { + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { if (fromVersion == 0) { var newConfigObjectNode = (ObjectNode) oldConfiguration; + if (!newConfigObjectNode.has(OLD_DATA_MAPPING_PROPERTY_NAME)) { + throw new TbNodeException("property to update: '" + OLD_DATA_MAPPING_PROPERTY_NAME + "' doesn't exists in configuration!"); + } + newConfigObjectNode.set(DATA_MAPPING_PROPERTY_NAME, newConfigObjectNode.get(OLD_DATA_MAPPING_PROPERTY_NAME)); + newConfigObjectNode.remove(OLD_DATA_MAPPING_PROPERTY_NAME); newConfigObjectNode.put(FETCH_TO_PROPERTY_NAME, FetchTo.METADATA.name()); return new TbPair<>(true, newConfigObjectNode); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index c89d7c4b59..3c508bda14 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -35,7 +35,7 @@ import java.util.Arrays; @RuleNode( type = ComponentType.ENRICHMENT, name = "related attributes", - configClazz = TbGetRelatedAttrNodeConfiguration.class, + configClazz = TbGetRelatedDataNodeConfiguration.class, nodeDescription = "Add Originators Related Entity Attributes or Latest Telemetry into Message Metadata/Data", nodeDetails = "Related Entity found using configured relation direction and Relation Type. " + "If multiple Related Entities are found, only first Entity is used for attributes enrichment, other entities are discarded. " + @@ -45,21 +45,21 @@ import java.util.Arrays; "metadata.temperature.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeRelatedAttributesConfig") -public class TbGetRelatedAttributeNode extends TbAbstractGetEntityAttrNode { +public class TbGetRelatedAttributeNode extends TbAbstractGetEntityDataNode { private static final String RELATED_ENTITY_NOT_FOUND_MESSAGE = "Failed to find related entity to message originator using relation query specified in the configuration!"; @Override - public TbGetRelatedAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - var config = TbNodeUtils.convert(configuration, TbGetRelatedAttrNodeConfiguration.class); - checkIfMappingIsNotEmptyOrElseThrow(config.getAttrMapping()); + public TbGetRelatedDataNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + var config = TbNodeUtils.convert(configuration, TbGetRelatedDataNodeConfiguration.class); + checkIfMappingIsNotEmptyOrElseThrow(config.getDataMapping()); checkDataToFetchSupportedOrElseThrow(config.getDataToFetch()); return config; } @Override public ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { - var relatedAttrConfig = (TbGetRelatedAttrNodeConfiguration) config; + var relatedAttrConfig = (TbGetRelatedDataNodeConfiguration) config; return Futures.transformAsync( EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, originator, relatedAttrConfig.getRelationsQuery()), checkIfEntityIsPresentOrThrow(RELATED_ENTITY_NOT_FOUND_MESSAGE), diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedDataNodeConfiguration.java similarity index 82% rename from rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java rename to rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedDataNodeConfiguration.java index 3f4d95a08f..4c78915ae4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedDataNodeConfiguration.java @@ -27,16 +27,16 @@ import java.util.HashMap; @Data @EqualsAndHashCode(callSuper = true) -public class TbGetRelatedAttrNodeConfiguration extends TbGetEntityAttrNodeConfiguration { +public class TbGetRelatedDataNodeConfiguration extends TbGetEntityDataNodeConfiguration { private RelationsQuery relationsQuery; @Override - public TbGetRelatedAttrNodeConfiguration defaultConfiguration() { - var configuration = new TbGetRelatedAttrNodeConfiguration(); - var attrMapping = new HashMap(); - attrMapping.putIfAbsent("serialNumber", "sn"); - configuration.setAttrMapping(attrMapping); + public TbGetRelatedDataNodeConfiguration defaultConfiguration() { + var configuration = new TbGetRelatedDataNodeConfiguration(); + var dataMapping = new HashMap(); + dataMapping.putIfAbsent("serialNumber", "sn"); + configuration.setDataMapping(dataMapping); configuration.setDataToFetch(DataToFetch.ATTRIBUTES); configuration.setFetchTo(FetchTo.METADATA); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index 8ff44e297c..aac8d8d3bf 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -33,7 +33,7 @@ import org.thingsboard.server.common.data.util.TbPair; @RuleNode( type = ComponentType.ENRICHMENT, name = "tenant attributes", - configClazz = TbGetEntityAttrNodeConfiguration.class, + configClazz = TbGetEntityDataNodeConfiguration.class, nodeDescription = "Add Originators Tenant Attributes or Latest Telemetry into Message Metadata/Data", nodeDetails = "If Attributes enrichment configured, server scope attributes are added into Message Metadata/Data. " + "If Latest Telemetry enrichment configured, latest telemetry added into Metadata/Data. " + @@ -41,12 +41,12 @@ import org.thingsboard.server.common.data.util.TbPair; "metadata.temperature.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbEnrichmentNodeTenantAttributesConfig") -public class TbGetTenantAttributeNode extends TbAbstractGetEntityAttrNode { +public class TbGetTenantAttributeNode extends TbAbstractGetEntityDataNode { @Override - public TbGetEntityAttrNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { - var config = TbNodeUtils.convert(configuration, TbGetEntityAttrNodeConfiguration.class); - checkIfMappingIsNotEmptyOrElseThrow(config.getAttrMapping()); + public TbGetEntityDataNodeConfiguration loadNodeConfiguration(TbNodeConfiguration configuration) throws TbNodeException { + var config = TbNodeUtils.convert(configuration, TbGetEntityDataNodeConfiguration.class); + checkIfMappingIsNotEmptyOrElseThrow(config.getDataMapping()); checkDataToFetchSupportedOrElseThrow(config.getDataToFetch()); return config; } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java index 201992e949..54e2f3bd4b 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java @@ -112,14 +112,14 @@ public class TbGetCustomerAttributeNodeTest { @Mock private DeviceService deviceServiceMock; private TbGetCustomerAttributeNode node; - private TbGetEntityAttrNodeConfiguration config; + private TbGetEntityDataNodeConfiguration config; private TbNodeConfiguration nodeConfiguration; private TbMsg msg; @BeforeEach public void setUp() { node = new TbGetCustomerAttributeNode(); - config = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + config = new TbGetEntityDataNodeConfiguration().defaultConfiguration(); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); } @@ -174,7 +174,7 @@ public class TbGetCustomerAttributeNodeTest { // THEN assertThat(node.config).isEqualTo(config); - assertThat(config.getAttrMapping()).isEqualTo(Map.of("alarmThreshold", "threshold")); + assertThat(config.getDataMapping()).isEqualTo(Map.of("alarmThreshold", "threshold")); assertThat(config.getDataToFetch()).isEqualTo(DataToFetch.ATTRIBUTES); assertThat(node.fetchTo).isEqualTo(FetchTo.METADATA); } @@ -182,7 +182,7 @@ public class TbGetCustomerAttributeNodeTest { @Test public void givenCustomConfig_whenInit_thenOK() throws TbNodeException { // GIVEN - config.setAttrMapping(Map.of( + config.setDataMapping(Map.of( "sourceAttr1", "targetKey1", "sourceAttr2", "targetKey2", "sourceAttr3", "targetKey3")); @@ -195,7 +195,7 @@ public class TbGetCustomerAttributeNodeTest { // THEN assertThat(node.config).isEqualTo(config); - assertThat(config.getAttrMapping()).isEqualTo(Map.of( + assertThat(config.getDataMapping()).isEqualTo(Map.of( "sourceAttr1", "targetKey1", "sourceAttr2", "targetKey2", "sourceAttr3", "targetKey3")); @@ -208,7 +208,7 @@ public class TbGetCustomerAttributeNodeTest { // GIVEN var expectedExceptionMessage = "At least one mapping entry should be specified!"; - config.setAttrMapping(Collections.emptyMap()); + config.setDataMapping(Collections.emptyMap()); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); // WHEN @@ -456,7 +456,7 @@ public class TbGetCustomerAttributeNodeTest { @Test public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { - var defaultConfig = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + var defaultConfig = new TbGetEntityDataNodeConfiguration().defaultConfiguration(); var node = new TbGetCustomerAttributeNode(); String oldConfig = "{\"attrMapping\":{\"alarmThreshold\":\"threshold\"},\"telemetry\":false}"; JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); @@ -466,7 +466,7 @@ public class TbGetCustomerAttributeNodeTest { } private void prepareMsgAndConfig(FetchTo fetchTo, DataToFetch dataToFetch, EntityId originator) { - config.setAttrMapping(Map.of( + config.setDataMapping(Map.of( "sourceKey1", "targetKey1", "${metaDataPattern1}", "$[messageBodyPattern1]", "$[messageBodyPattern2]", "${metaDataPattern2}")); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java index 6b162d08fb..45f42a95a7 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetOriginatorFieldsNodeTest.java @@ -44,6 +44,7 @@ import java.util.Collections; import java.util.Map; import java.util.UUID; import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -111,7 +112,7 @@ public class TbGetOriginatorFieldsNodeTest { // THEN assertThat(node.config).isEqualTo(config); - assertThat(config.getFieldsMapping()).isEqualTo(Map.of( + assertThat(config.getDataMapping()).isEqualTo(Map.of( "name", "originatorName", "type", "originatorType")); assertThat(config.isIgnoreNullStrings()).isEqualTo(false); @@ -122,7 +123,7 @@ public class TbGetOriginatorFieldsNodeTest { @Test public void givenCustomConfig_whenInit_thenOK() throws TbNodeException { // GIVEN - config.setFieldsMapping(Map.of( + config.setDataMapping(Map.of( "email", "originatorEmail", "title", "originatorTitle", "country", "originatorCountry")); @@ -135,7 +136,7 @@ public class TbGetOriginatorFieldsNodeTest { // THEN assertThat(node.config).isEqualTo(config); - assertThat(config.getFieldsMapping()).isEqualTo(Map.of( + assertThat(config.getDataMapping()).isEqualTo(Map.of( "email", "originatorEmail", "title", "originatorTitle", "country", "originatorCountry")); @@ -159,14 +160,14 @@ public class TbGetOriginatorFieldsNodeTest { } @Test - public void givenValidMsgAndFetchToData_whenOnMsg_thenShouldTellSuccessAndFetchToData() { + public void givenValidMsgAndFetchToData_whenOnMsg_thenShouldTellSuccessAndFetchToData() throws TbNodeException, ExecutionException, InterruptedException { // GIVEN var device = new Device(); device.setId(DUMMY_DEVICE_ORIGINATOR); device.setName("Test device"); device.setType("Test device type"); - config.setFieldsMapping(Map.of( + config.setDataMapping(Map.of( "name", "originatorName", "type", "originatorType", "label", "originatorLabel")); @@ -200,14 +201,14 @@ public class TbGetOriginatorFieldsNodeTest { } @Test - public void givenValidMsgAndFetchToMetaData_whenOnMsg_thenShouldTellSuccessAndFetchToMetaData() { + public void givenValidMsgAndFetchToMetaData_whenOnMsg_thenShouldTellSuccessAndFetchToMetaData() throws TbNodeException, ExecutionException, InterruptedException { // GIVEN var device = new Device(); device.setId(DUMMY_DEVICE_ORIGINATOR); device.setName("Test device"); device.setType("Test device type"); - config.setFieldsMapping(Map.of( + config.setDataMapping(Map.of( "name", "originatorName", "type", "originatorType", "label", "originatorLabel")); @@ -248,14 +249,14 @@ public class TbGetOriginatorFieldsNodeTest { } @Test - public void givenNullEntityFieldsAndIgnoreNullStringsFalse_whenOnMsg_thenShouldTellSuccessAndFetchNullField() { + public void givenNullEntityFieldsAndIgnoreNullStringsFalse_whenOnMsg_thenShouldTellSuccessAndFetchNullField() throws TbNodeException, ExecutionException, InterruptedException { // GIVEN var device = new Device(); device.setId(DUMMY_DEVICE_ORIGINATOR); device.setName("Test device"); device.setType("Test device type"); - config.setFieldsMapping(Map.of( + config.setDataMapping(Map.of( "name", "originatorName", "type", "originatorType", "label", "originatorLabel")); @@ -299,7 +300,7 @@ public class TbGetOriginatorFieldsNodeTest { @Test public void givenEmptyFieldsMapping_whenInit_thenException() { // GIVEN - config.setFieldsMapping(Collections.emptyMap()); + config.setDataMapping(Collections.emptyMap()); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); // WHEN @@ -311,9 +312,9 @@ public class TbGetOriginatorFieldsNodeTest { } @Test - public void givenUnsupportedEntityType_whenOnMsg_thenShouldTellFailureWithSameMsg() { + public void givenUnsupportedEntityType_whenOnMsg_thenShouldTellFailureWithSameMsg() throws TbNodeException, ExecutionException, InterruptedException { // GIVEN - config.setFieldsMapping(Map.of( + config.setDataMapping(Map.of( "name", "originatorName", "type", "originatorType", "label", "originatorLabel")); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index a9a04fb3df..b222e11d20 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -34,9 +34,21 @@ import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.data.RelationsQuery; -import org.thingsboard.server.common.data.*; +import org.thingsboard.server.common.data.Customer; +import org.thingsboard.server.common.data.Dashboard; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.common.data.id.*; +import org.thingsboard.server.common.data.id.AssetId; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DashboardId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EntityViewId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; @@ -54,7 +66,12 @@ import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.timeseries.TimeseriesService; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.UUID; import java.util.concurrent.Callable; import static org.assertj.core.api.Assertions.assertThat; @@ -102,7 +119,7 @@ public class TbGetRelatedAttributeNodeTest { @Mock private DeviceService deviceServiceMock; private TbGetRelatedAttributeNode node; - private TbGetRelatedAttrNodeConfiguration config; + private TbGetRelatedDataNodeConfiguration config; private TbNodeConfiguration nodeConfiguration; private EntityRelation entityRelation; private TbMsg msg; @@ -110,7 +127,7 @@ public class TbGetRelatedAttributeNodeTest { @BeforeEach public void setUp() { node = new TbGetRelatedAttributeNode(); - config = new TbGetRelatedAttrNodeConfiguration().defaultConfiguration(); + config = new TbGetRelatedDataNodeConfiguration().defaultConfiguration(); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); entityRelation = new EntityRelation(); } @@ -151,9 +168,9 @@ public class TbGetRelatedAttributeNodeTest { node.init(ctxMock, nodeConfiguration); // THEN - var nodeConfig = (TbGetRelatedAttrNodeConfiguration) node.config; + var nodeConfig = (TbGetRelatedDataNodeConfiguration) node.config; assertThat(nodeConfig).isEqualTo(config); - assertThat(nodeConfig.getAttrMapping()).isEqualTo(Map.of("serialNumber", "sn")); + assertThat(nodeConfig.getDataMapping()).isEqualTo(Map.of("serialNumber", "sn")); assertThat(nodeConfig.getDataToFetch()).isEqualTo(DataToFetch.ATTRIBUTES); assertThat(node.fetchTo).isEqualTo(FetchTo.METADATA); @@ -169,7 +186,7 @@ public class TbGetRelatedAttributeNodeTest { @Test public void givenCustomConfig_whenInit_thenOK() throws TbNodeException { // GIVEN - config.setAttrMapping(Map.of( + config.setDataMapping(Map.of( "sourceAttr1", "targetKey1", "sourceAttr2", "targetKey2", "sourceAttr3", "targetKey3")); @@ -189,9 +206,9 @@ public class TbGetRelatedAttributeNodeTest { node.init(ctxMock, nodeConfiguration); // THEN - var nodeConfig = (TbGetRelatedAttrNodeConfiguration) node.config; + var nodeConfig = (TbGetRelatedDataNodeConfiguration) node.config; assertThat(nodeConfig).isEqualTo(config); - assertThat(nodeConfig.getAttrMapping()).isEqualTo(Map.of( + assertThat(nodeConfig.getDataMapping()).isEqualTo(Map.of( "sourceAttr1", "targetKey1", "sourceAttr2", "targetKey2", "sourceAttr3", "targetKey3" @@ -206,7 +223,7 @@ public class TbGetRelatedAttributeNodeTest { // GIVEN var expectedExceptionMessage = "At least one mapping entry should be specified!"; - config.setAttrMapping(Collections.emptyMap()); + config.setDataMapping(Collections.emptyMap()); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); // WHEN @@ -553,7 +570,7 @@ public class TbGetRelatedAttributeNodeTest { @Test public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { - var defaultConfig = new TbGetRelatedAttrNodeConfiguration().defaultConfiguration(); + var defaultConfig = new TbGetRelatedDataNodeConfiguration().defaultConfiguration(); var node = new TbGetRelatedAttributeNode(); String oldConfig = "{\"attrMapping\":{\"serialNumber\":\"sn\"}," + "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + @@ -575,13 +592,13 @@ public class TbGetRelatedAttributeNodeTest { var msgMetaData = new TbMsgMetaData(); String msgData; if (dataToFetch.equals(DataToFetch.FIELDS)) { - config.setAttrMapping(Map.of( + config.setDataMapping(Map.of( "id", "$[messageBodyPattern]", "name", "${metaDataPattern}")); msgMetaData.putValue("metaDataPattern", "relatedEntityName"); msgData = "{\"temp\":42,\"humidity\":77,\"messageBodyPattern\":\"relatedEntityId\"}"; } else { - config.setAttrMapping(Map.of( + config.setDataMapping(Map.of( "sourceKey1", "targetKey1", "${metaDataPattern1}", "$[messageBodyPattern1]", "$[messageBodyPattern2]", "${metaDataPattern2}")); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index 5c56561a48..855adea614 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -93,14 +93,14 @@ public class TbGetTenantAttributeNodeTest { @Mock private TimeseriesService timeseriesServiceMock; private TbGetTenantAttributeNode node; - private TbGetEntityAttrNodeConfiguration config; + private TbGetEntityDataNodeConfiguration config; private TbNodeConfiguration nodeConfiguration; private TbMsg msg; @BeforeEach public void setUp() { node = new TbGetTenantAttributeNode(); - config = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + config = new TbGetEntityDataNodeConfiguration().defaultConfiguration(); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); } @@ -155,7 +155,7 @@ public class TbGetTenantAttributeNodeTest { // THEN assertThat(node.config).isEqualTo(config); - assertThat(config.getAttrMapping()).isEqualTo(Map.of("alarmThreshold", "threshold")); + assertThat(config.getDataMapping()).isEqualTo(Map.of("alarmThreshold", "threshold")); assertThat(config.getDataToFetch()).isEqualTo(DataToFetch.ATTRIBUTES); assertThat(node.fetchTo).isEqualTo(FetchTo.METADATA); } @@ -163,7 +163,7 @@ public class TbGetTenantAttributeNodeTest { @Test public void givenCustomConfig_whenInit_thenOK() throws TbNodeException { // GIVEN - config.setAttrMapping(Map.of( + config.setDataMapping(Map.of( "sourceAttr1", "targetKey1", "sourceAttr2", "targetKey2", "sourceAttr3", "targetKey3")); @@ -176,7 +176,7 @@ public class TbGetTenantAttributeNodeTest { // THEN assertThat(node.config).isEqualTo(config); - assertThat(config.getAttrMapping()).isEqualTo(Map.of( + assertThat(config.getDataMapping()).isEqualTo(Map.of( "sourceAttr1", "targetKey1", "sourceAttr2", "targetKey2", "sourceAttr3", "targetKey3")); @@ -189,7 +189,7 @@ public class TbGetTenantAttributeNodeTest { // GIVEN var expectedExceptionMessage = "At least one mapping entry should be specified!"; - config.setAttrMapping(Collections.emptyMap()); + config.setDataMapping(Collections.emptyMap()); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); // WHEN @@ -386,7 +386,7 @@ public class TbGetTenantAttributeNodeTest { @Test public void givenOldConfig_whenUpgrade_thenShouldReturnSuccessResult() throws Exception { - var defaultConfig = new TbGetEntityAttrNodeConfiguration().defaultConfiguration(); + var defaultConfig = new TbGetEntityDataNodeConfiguration().defaultConfiguration(); var node = new TbGetTenantAttributeNode(); String oldConfig = "{\"attrMapping\":{\"alarmThreshold\":\"threshold\"},\"telemetry\":false}"; JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); @@ -396,7 +396,7 @@ public class TbGetTenantAttributeNodeTest { } private void prepareMsgAndConfig(FetchTo fetchTo, DataToFetch dataToFetch, EntityId originator) { - config.setAttrMapping(Map.of( + config.setDataMapping(Map.of( "sourceKey1", "targetKey1", "${metaDataPattern1}", "$[messageBodyPattern1]", "$[messageBodyPattern2]", "${metaDataPattern2}")); From 97a39729f39fba3427239c357e0a0d983a9eaa17 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 19 May 2023 14:16:54 +0300 Subject: [PATCH 066/207] fixed testSaveRuleChainMetadataWithVersionedNodes test --- .../server/controller/RuleChainControllerTest.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java index eb989ac5b6..f3ed223e4f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java @@ -32,6 +32,7 @@ import org.thingsboard.rule.engine.action.TbCreateAlarmNode; import org.thingsboard.rule.engine.action.TbCreateAlarmNodeConfiguration; import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.rule.engine.metadata.TbGetRelatedAttributeNode; +import org.thingsboard.rule.engine.metadata.TbGetRelatedDataNodeConfiguration; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; @@ -152,12 +153,7 @@ public class RuleChainControllerTest extends AbstractControllerTest { "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + "\"fetchLastLevelOnly\":false},\"telemetry\":false}"; - String newConfig = "{\"fetchTo\":\"METADATA\"," + - "\"attrMapping\":{\"serialNumber\":\"sn\"}," + - "\"dataToFetch\":\"ATTRIBUTES\"," + - "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + - "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + - "\"fetchLastLevelOnly\":false}}"; + String newConfig = JacksonUtil.toString(new TbGetRelatedDataNodeConfiguration().defaultConfiguration()); var ruleChainMetaData = createRuleChainMetadataWithTbVersionedNodes( ruleChainId, From a7410e99124948de0039e5a2bcd6570d677f3ac9 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 19 May 2023 14:23:31 +0300 Subject: [PATCH 067/207] fixed license format --- .../service/install/update/DefaultDataUpdateService.java | 8 ++++---- .../thingsboard/server/dao/rule/BaseRuleChainService.java | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 31988394ab..59f4b9cc82 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 8c25a97298..92146aa427 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -1,12 +1,12 @@ /** * Copyright © 2016-2023 The Thingsboard Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. From 87cbe96c3b7b13d2db4ebf7b5a84e655b38ed731 Mon Sep 17 00:00:00 2001 From: kalytka Date: Fri, 19 May 2023 15:07:25 +0300 Subject: [PATCH 068/207] rule node style improve --- .../home/components/details-panel.component.html | 2 +- .../home/components/details-panel.component.scss | 10 ++++++++++ .../relation/relation-filters.component.html | 10 +++++----- .../relation/relation-filters.component.scss | 1 + .../pages/rulechain/rule-node-details.component.html | 2 +- .../pages/rulechain/rule-node-details.component.scss | 6 +++++- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/details-panel.component.html b/ui-ngx/src/app/modules/home/components/details-panel.component.html index 15df7e99e5..e82ee068d5 100644 --- a/ui-ngx/src/app/modules/home/components/details-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/details-panel.component.html @@ -65,6 +65,6 @@

-
+
diff --git a/ui-ngx/src/app/modules/home/components/details-panel.component.scss b/ui-ngx/src/app/modules/home/components/details-panel.component.scss index 9002246841..b73eb5d58d 100644 --- a/ui-ngx/src/app/modules/home/components/details-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/details-panel.component.scss @@ -20,12 +20,22 @@ height: 100%; display: flex; flex-direction: column; + .mat-toolbar.details-toolbar { padding: 0; } } :host ::ng-deep { + + .reset-style { + color: rgba(0, 0, 0, 0.6);; + //font-family: "Arial"; + line-height: 24px; + //font-weight: 500; + letter-spacing: 0.5px; + } + .mat-toolbar-tools { height: 100%; min-height: 60px; diff --git a/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html b/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html index bfc639e6b4..71965c4ba1 100644 --- a/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html +++ b/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.html @@ -22,13 +22,13 @@ fxLayoutAlign="start center" formArrayName="relationFilters" *ngFor="let relationFilterControl of relationFiltersFormArray.controls; let $index = index">
-
- + - @@ -49,7 +49,7 @@ relation.any-relation
-
+
diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.scss b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.scss index 4995d5c06d..a576472592 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.scss +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rule-node-details.component.scss @@ -27,12 +27,16 @@ display: flex; flex-direction: column; gap: 8px; - margin-bottom: 5px; + + @media #{$mat-gt-sm} { + margin-bottom: 24px; + } } @media #{$mat-gt-sm} { flex-direction: row; gap: 8px; + align-items: center; .node-setting { margin-top: 5px; From e39e1d61ff537d165ace2ec7c8f3ff0a7201089c Mon Sep 17 00:00:00 2001 From: kalytka Date: Fri, 19 May 2023 15:11:15 +0300 Subject: [PATCH 069/207] Refactoring --- .../modules/home/components/details-panel.component.html | 2 +- .../modules/home/components/details-panel.component.scss | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/details-panel.component.html b/ui-ngx/src/app/modules/home/components/details-panel.component.html index e82ee068d5..720cdffd83 100644 --- a/ui-ngx/src/app/modules/home/components/details-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/details-panel.component.html @@ -65,6 +65,6 @@ -
+
diff --git a/ui-ngx/src/app/modules/home/components/details-panel.component.scss b/ui-ngx/src/app/modules/home/components/details-panel.component.scss index b73eb5d58d..2a820b9f54 100644 --- a/ui-ngx/src/app/modules/home/components/details-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/details-panel.component.scss @@ -20,7 +20,6 @@ height: 100%; display: flex; flex-direction: column; - .mat-toolbar.details-toolbar { padding: 0; } @@ -28,11 +27,9 @@ :host ::ng-deep { - .reset-style { - color: rgba(0, 0, 0, 0.6);; - //font-family: "Arial"; + .details-panel-style { + color: rgba(0, 0, 0, 0.6); line-height: 24px; - //font-weight: 500; letter-spacing: 0.5px; } From dfbd8801887e3b37fa239393ace974010170e83c Mon Sep 17 00:00:00 2001 From: kalytka Date: Fri, 19 May 2023 16:10:29 +0300 Subject: [PATCH 070/207] Refactoring --- .../modules/home/components/details-panel.component.html | 2 +- .../modules/home/components/details-panel.component.scss | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/details-panel.component.html b/ui-ngx/src/app/modules/home/components/details-panel.component.html index 720cdffd83..15df7e99e5 100644 --- a/ui-ngx/src/app/modules/home/components/details-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/details-panel.component.html @@ -65,6 +65,6 @@ -
+
diff --git a/ui-ngx/src/app/modules/home/components/details-panel.component.scss b/ui-ngx/src/app/modules/home/components/details-panel.component.scss index 2a820b9f54..9002246841 100644 --- a/ui-ngx/src/app/modules/home/components/details-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/details-panel.component.scss @@ -26,13 +26,6 @@ } :host ::ng-deep { - - .details-panel-style { - color: rgba(0, 0, 0, 0.6); - line-height: 24px; - letter-spacing: 0.5px; - } - .mat-toolbar-tools { height: 100%; min-height: 60px; From 490ad63ab69eff1c7abc2e5424c8bab9abd308d8 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 19 May 2023 17:27:52 +0300 Subject: [PATCH 071/207] updated rule node upgrade logic --- .../update/DefaultDataUpdateService.java | 64 +++++++------------ .../server/dao/rule/BaseRuleChainService.java | 31 ++------- 2 files changed, 29 insertions(+), 66 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 59f4b9cc82..2c63b9987d 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -27,7 +27,6 @@ import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; @@ -86,10 +85,11 @@ import org.thingsboard.server.service.bean.BeanDiscoveryService; import org.thingsboard.server.service.install.InstallScripts; import org.thingsboard.server.service.install.SystemDataLoaderService; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -221,35 +221,26 @@ public class DefaultDataUpdateService implements DataUpdateService { private void upgradeRuleNodes() { try { log.info("Lookup rule nodes to upgrade ..."); - ArrayList tbVersionedNodes = getTbVersionedNodes(); - log.info("Found {} versioned nodes to check for upgrade!", tbVersionedNodes.size()); - for (TbVersionedNode tbVersionedNode : tbVersionedNodes) { - String ruleNodeType = tbVersionedNode.getClass().getName(); - String ruleNodeTypeForLogs = tbVersionedNode.getClass().getSimpleName(); - int toVersion = tbVersionedNode.getCurrentVersion(); + var nodeClassToVersionMap = getNodeClassToVersionMap(); + log.info("Found {} versioned nodes to check for upgrade!", nodeClassToVersionMap.size()); + nodeClassToVersionMap.forEach((clazz, toVersion) -> { + var ruleNodeType = clazz.getName(); + var ruleNodeTypeForLogs = clazz.getSimpleName(); log.info("Going to check for nodes with type: {} to upgrade to version: {}.", ruleNodeTypeForLogs, toVersion); var ruleNodesToUpdate = new PageDataIterable<>( - pageLink -> - ruleChainService.findAllRuleNodesByTypeAndVersionLessThan( - ruleNodeType, - toVersion, - pageLink - ), - 1024 + pageLink -> ruleChainService.findAllRuleNodesByTypeAndVersionLessThan(ruleNodeType, toVersion, pageLink), 1024 ); if (Iterables.isEmpty(ruleNodesToUpdate)) { log.info("There are no active nodes with type: {}, or all nodes with this type already set to latest version!", ruleNodeTypeForLogs); } else { - for (RuleNode ruleNode : ruleNodesToUpdate) { - RuleNodeId ruleNodeId = ruleNode.getId(); + for (var ruleNode : ruleNodesToUpdate) { + var ruleNodeId = ruleNode.getId(); var oldConfiguration = ruleNode.getConfiguration(); int fromVersion = ruleNode.getConfigurationVersion(); log.info("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", - ruleNodeId, - ruleNodeTypeForLogs, - fromVersion, - toVersion); + ruleNodeId, ruleNodeTypeForLogs, fromVersion, toVersion); try { + var tbVersionedNode = (TbVersionedNode) clazz.getDeclaredConstructor().newInstance(); TbPair upgradeRuleNodeConfigurationResult = tbVersionedNode.upgrade(fromVersion, oldConfiguration); if (upgradeRuleNodeConfigurationResult.getFirst()) { ruleNode.setConfiguration(upgradeRuleNodeConfigurationResult.getSecond()); @@ -257,45 +248,34 @@ public class DefaultDataUpdateService implements DataUpdateService { ruleNode.setConfigurationVersion(toVersion); ruleChainService.saveRuleNode(TenantId.SYS_TENANT_ID, ruleNode); log.info("Successfully upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", - ruleNodeId, - ruleNodeTypeForLogs, - fromVersion, - toVersion); - } catch (TbNodeException e) { + ruleNodeId, ruleNodeTypeForLogs, fromVersion, toVersion); + } catch (Exception e) { log.warn("Failed to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {} due to: ", - ruleNodeId, - ruleNodeTypeForLogs, - fromVersion, - toVersion, - e); + ruleNodeId, ruleNodeTypeForLogs, fromVersion, toVersion, e); } } } - } + }); log.info("Finished rule nodes upgrade!"); } catch (Exception e) { log.error("Unexpected error during rule nodes upgrade: ", e); } } - private ArrayList getTbVersionedNodes() { + private Map, Integer> getNodeClassToVersionMap() { var ruleNodeDefinitions = beanDiscoveryService.discoverBeansByAnnotationType( org.thingsboard.rule.engine.api.RuleNode.class ); - var tbVersionedNodes = new ArrayList(); + var tbVersionedNodes = new HashMap, Integer>(); for (var def : ruleNodeDefinitions) { String clazzName = def.getBeanClassName(); try { var clazz = Class.forName(clazzName); if (TbVersionedNode.class.isAssignableFrom(clazz)) { - tbVersionedNodes.add((TbVersionedNode) clazz.getDeclaredConstructor().newInstance()); - } - } catch (NoSuchMethodException | - InstantiationException | - IllegalAccessException | - InvocationTargetException | - ClassNotFoundException e - ) { + TbVersionedNode tbVersionedNode = (TbVersionedNode) clazz.getDeclaredConstructor().newInstance(); + tbVersionedNodes.put(clazz, tbVersionedNode.getCurrentVersion()); + } + } catch (Exception e) { log.warn("Failed to create instance of rule node type: {} due to: ", clazzName, e); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 92146aa427..7d85087703 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -199,10 +199,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC int toVersion = tbVersionedNode.getCurrentVersion(); if (fromVersion < toVersion) { log.debug("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", - ruleNodeId, - ruleNodeType, - fromVersion, - toVersion); + ruleNodeId, ruleNodeType, fromVersion, toVersion); try { TbPair upgradeResult = tbVersionedNode.upgrade(fromVersion, node.getConfiguration()); if (upgradeResult.getFirst()) { @@ -210,33 +207,19 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } node.setConfigurationVersion(toVersion); log.debug("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}", - ruleNodeId, - ruleNodeType, - ruleChainId, - fromVersion, - toVersion); + ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion); } catch (TbNodeException e) { log.warn("Failed to upgrade rule node with id: {} type: {} rule chain id: {} fromVersion: {} toVersion: {} due to: ", - ruleNodeId, - ruleNodeType, - ruleChainId, - fromVersion, - toVersion, - e); + ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion, e); } } else { log.debug("Rule node with id: {} type: {} ruleChainId: {} already set to latest version!", - ruleNodeId, - ruleChainId, - ruleNodeType); + ruleNodeId, ruleChainId, ruleNodeType); } } - } catch (ClassNotFoundException | - InvocationTargetException | - InstantiationException | - IllegalAccessException | - NoSuchMethodException e) { - log.error("Failed to create instance of rule node with id: {} type: {}, rule chain id: {}", ruleNodeId, ruleNodeType, ruleChainId); + } catch (Exception e) { + log.error("Failed to create instance of rule node with id: {} type: {}, rule chain id: {}", + ruleNodeId, ruleNodeType, ruleChainId); } RuleNode savedNode = ruleNodeDao.save(tenantId, node); relations.add(new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(), From 7e7b5b17e71131dfd72d7857f8ad20ba637af186 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 19 May 2023 17:32:17 +0300 Subject: [PATCH 072/207] refactoring --- .../controller/TbResourceController.java | 10 +++++-- .../resource/DefaultTbResourceService.java | 9 +++--- .../service/resource/TbResourceService.java | 5 ++-- .../sql/BaseTbResourceServiceTest.java | 26 +++++++++++++---- .../server/dao/resource/ResourceService.java | 5 ++-- .../common/data/TbResourceInfoFilter.java | 29 +++++++++++++++++++ .../dao/resource/BaseResourceService.java | 11 ++++--- .../dao/resource/TbResourceInfoDao.java | 5 ++-- .../sql/resource/JpaTbResourceInfoDao.java | 16 ++++++---- .../server/dao/service/TenantServiceTest.java | 6 +++- 10 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfoFilter.java diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index ab48214981..4196599557 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.lwm2m.LwM2mObject; @@ -166,11 +167,14 @@ public class TbResourceController extends BaseController { @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); - ResourceType resourceTypeValue = StringUtils.isNotEmpty(resourceType) ? ResourceType.valueOf(resourceType) : null; + TbResourceInfoFilter.TbResourceInfoFilterBuilder filter = TbResourceInfoFilter.builder(); + filter.tenantId(getTenantId()); + filter.resourceType(StringUtils.isNotEmpty(resourceType) ? ResourceType.valueOf(resourceType) : null); + if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { - return checkNotNull(resourceService.findTenantResourcesByTenantId(getTenantId(), resourceTypeValue, pageLink)); + return checkNotNull(resourceService.findTenantResourcesByTenantId(filter.build(), pageLink)); } else { - return checkNotNull(resourceService.findAllTenantResourcesByTenantId(getTenantId(), resourceTypeValue, pageLink)); + return checkNotNull(resourceService.findAllTenantResourcesByTenantId(filter.build(), pageLink)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java index de01c9bf54..41ed04ac8f 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java @@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -76,13 +77,13 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements } @Override - public PageData findAllTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { - return resourceService.findAllTenantResourcesByTenantId(tenantId, resourceType, pageLink); + public PageData findAllTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink) { + return resourceService.findAllTenantResourcesByTenantId(tbResourceInfoFilter, pageLink); } @Override - public PageData findTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { - return resourceService.findTenantResourcesByTenantId(tenantId, resourceType, pageLink); + public PageData findTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink) { + return resourceService.findTenantResourcesByTenantId(tbResourceInfoFilter, pageLink); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java index 6e26d9ffe8..d80af9b513 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/TbResourceService.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.resource; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.lwm2m.LwM2mObject; @@ -35,9 +36,9 @@ public interface TbResourceService extends SimpleTbEntityService { TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId); - PageData findAllTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + PageData findAllTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink); - PageData findTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + PageData findTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink); List findLwM2mObject(TenantId tenantId, String sortOrder, diff --git a/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java b/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java index 364850e2fd..300ef0e4c5 100644 --- a/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java @@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.EntityInfo; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.User; @@ -356,7 +357,10 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { PageLink pageLink = new PageLink(16); PageData pageData; do { - pageData = resourceService.findTenantResourcesByTenantId(tenantId, null, pageLink); + TbResourceInfoFilter filter = TbResourceInfoFilter.builder() + .tenantId(tenantId) + .build(); + pageData = resourceService.findTenantResourcesByTenantId(filter, pageLink); loadedResources.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink(); @@ -371,7 +375,10 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resourceService.deleteResourcesByTenantId(tenantId); pageLink = new PageLink(31); - pageData = resourceService.findTenantResourcesByTenantId(tenantId, null, pageLink); + TbResourceInfoFilter filter = TbResourceInfoFilter.builder() + .tenantId(tenantId) + .build(); + pageData = resourceService.findTenantResourcesByTenantId(filter, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertTrue(pageData.getData().isEmpty()); @@ -417,7 +424,10 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { PageLink pageLink = new PageLink(10); PageData pageData; do { - pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, null, pageLink); + TbResourceInfoFilter filter = TbResourceInfoFilter.builder() + .tenantId(tenantId) + .build(); + pageData = resourceService.findAllTenantResourcesByTenantId(filter, pageLink); loadedResources.addAll(pageData.getData()); if (pageData.hasNext()) { pageLink = pageLink.nextPageLink(); @@ -432,14 +442,20 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resourceService.deleteResourcesByTenantId(tenantId); pageLink = new PageLink(100); - pageData = resourceService.findAllTenantResourcesByTenantId(tenantId, null, pageLink); + TbResourceInfoFilter filter = TbResourceInfoFilter.builder() + .tenantId(tenantId) + .build(); + pageData = resourceService.findAllTenantResourcesByTenantId(filter, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(pageData.getData().size(), 100); resourceService.deleteResourcesByTenantId(TenantId.SYS_TENANT_ID); pageLink = new PageLink(100); - pageData = resourceService.findAllTenantResourcesByTenantId(TenantId.SYS_TENANT_ID, null, pageLink); + filter = TbResourceInfoFilter.builder() + .tenantId(TenantId.SYS_TENANT_ID) + .build(); + pageData = resourceService.findAllTenantResourcesByTenantId(filter, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertTrue(pageData.getData().isEmpty()); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 2933c1a3c2..f561662a5e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -39,9 +40,9 @@ public interface ResourceService extends EntityDaoService { ListenableFuture findResourceInfoByIdAsync(TenantId tenantId, TbResourceId resourceId); - PageData findAllTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + PageData findAllTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink); - PageData findTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink); + PageData findTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink); List findTenantResourcesByResourceTypeAndObjectIds(TenantId tenantId, ResourceType lwm2mModel, String[] objectIds); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfoFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfoFilter.java new file mode 100644 index 0000000000..9057fc144b --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfoFilter.java @@ -0,0 +1,29 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data; + +import lombok.Builder; +import lombok.Data; +import org.thingsboard.server.common.data.id.TenantId; + +@Data +@Builder +public class TbResourceInfoFilter { + + private TenantId tenantId; + private ResourceType resourceType; + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 1e14e11f74..2bab06da6f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TbResourceId; @@ -103,17 +104,19 @@ public class BaseResourceService implements ResourceService { } @Override - public PageData findAllTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { + public PageData findAllTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink) { + TenantId tenantId = tbResourceInfoFilter.getTenantId(); log.trace("Executing findAllTenantResourcesByTenantId [{}]", tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - return resourceInfoDao.findAllTenantResourcesByTenantId(tenantId.getId(), resourceType == null ? null : resourceType.name(), pageLink); + return resourceInfoDao.findAllTenantResourcesByTenantId(tbResourceInfoFilter, pageLink); } @Override - public PageData findTenantResourcesByTenantId(TenantId tenantId, ResourceType resourceType, PageLink pageLink) { + public PageData findTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink) { + TenantId tenantId = tbResourceInfoFilter.getTenantId(); log.trace("Executing findTenantResourcesByTenantId [{}]", tenantId); validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - return resourceInfoDao.findTenantResourcesByTenantId(tenantId.getId(), resourceType == null ? null : resourceType.name(), pageLink); + return resourceInfoDao.findTenantResourcesByTenantId(tbResourceInfoFilter, pageLink); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java index e916ff6b71..6f6163b9c0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/TbResourceInfoDao.java @@ -16,6 +16,7 @@ package org.thingsboard.server.dao.resource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.Dao; @@ -24,8 +25,8 @@ import java.util.UUID; public interface TbResourceInfoDao extends Dao { - PageData findAllTenantResourcesByTenantId(UUID tenantId, String resourceType, PageLink pageLink); + PageData findAllTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink); - PageData findTenantResourcesByTenantId(UUID tenantId, String resourceType, PageLink pageLink); + PageData findTenantResourcesByTenantId(TbResourceInfoFilter tbResourceInfoFilter, PageLink pageLink); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java index 16154976c2..988b00f043 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/resource/JpaTbResourceInfoDao.java @@ -19,7 +19,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Component; +import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -51,22 +53,24 @@ public class JpaTbResourceInfoDao extends JpaAbstractSearchTextDao findAllTenantResourcesByTenantId(UUID tenantId, String resourceType, PageLink pageLink) { + public PageData findAllTenantResourcesByTenantId(TbResourceInfoFilter filter, PageLink pageLink) { + ResourceType resourceType = filter.getResourceType(); return DaoUtil.toPageData(resourceInfoRepository .findAllTenantResourcesByTenantId( - tenantId, + filter.getTenantId().getId(), TenantId.NULL_UUID, - resourceType, + resourceType == null ? null : resourceType.name(), Objects.toString(pageLink.getTextSearch(), ""), DaoUtil.toPageable(pageLink))); } @Override - public PageData findTenantResourcesByTenantId(UUID tenantId, String resourceType, PageLink pageLink) { + public PageData findTenantResourcesByTenantId(TbResourceInfoFilter filter, PageLink pageLink) { + ResourceType resourceType = filter.getResourceType(); return DaoUtil.toPageData(resourceInfoRepository .findTenantResourcesByTenantId( - tenantId, - resourceType, + filter.getTenantId().getId(), + resourceType == null ? null : resourceType.name(), Objects.toString(pageLink.getTextSearch(), ""), DaoUtil.toPageable(pageLink))); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java index 74af3c0850..5872a5846b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/TenantServiceTest.java @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.TbResourceInfoFilter; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantInfo; import org.thingsboard.server.common.data.TenantProfile; @@ -505,8 +506,11 @@ public class TenantServiceTest extends AbstractServiceTest { assertThat(resourceService.findResourceById(tenant.getId(), resource.getId())) .as("resource").isNull(); PageLink pageLinkResources = new PageLink(1); + TbResourceInfoFilter filter = TbResourceInfoFilter.builder() + .tenantId(tenantId) + .build(); PageData tenantResources = - resourceService.findAllTenantResourcesByTenantId(tenant.getId(), null, pageLinkResources); + resourceService.findAllTenantResourcesByTenantId(filter, pageLinkResources); Assert.assertEquals(0, tenantResources.getTotalElements()); } From 130bb84657ca249318d627cc469faee2986df988 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 19 May 2023 17:54:27 +0300 Subject: [PATCH 073/207] UI: Widget config improvement --- .../alias/entity-alias-select.component.html | 7 + .../alias/entity-alias-select.component.ts | 17 +- .../add-widget-dialog.component.ts | 4 +- .../filter/filter-select.component.html | 7 + .../filter/filter-select.component.ts | 13 +- .../home/components/home-components.module.ts | 6 + .../widget/data-keys.component.html | 61 +- .../widget/data-keys.component.scss | 28 +- .../components/widget/data-keys.component.ts | 132 +++-- .../widget/datasource.component.html | 95 ++++ .../widget/datasource.component.models.ts | 21 + .../widget/datasource.component.scss | 33 ++ .../components/widget/datasource.component.ts | 243 ++++++++ .../widget/datasources.component.html | 89 +++ .../widget/datasources.component.scss | 83 +++ .../widget/datasources.component.ts | 236 ++++++++ .../widget/widget-config.component.html | 523 ++++++------------ .../widget/widget-config.component.models.ts | 6 +- .../widget/widget-config.component.scss | 160 +----- .../widget/widget-config.component.ts | 386 ++++--------- .../home/components/widget/widget-config.scss | 165 ++++++ .../components/color-input.component.html | 7 +- .../components/color-input.component.scss | 3 + .../components/color-input.component.ts | 12 +- .../material-icon-select.component.html | 9 +- .../material-icon-select.component.scss | 29 +- .../material-icon-select.component.ts | 15 +- .../components/toggle-header.component.scss | 7 +- .../assets/locale/locale.constant-en_US.json | 20 +- ui-ngx/src/styles.scss | 21 + 30 files changed, 1528 insertions(+), 910 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/datasource.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/datasource.component.models.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/datasource.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/datasource.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/datasources.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/datasources.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/datasources.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/widget-config.scss diff --git a/ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.html b/ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.html index db13e8dcee..574209c6f8 100644 --- a/ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.html +++ b/ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.html @@ -31,6 +31,13 @@ (click)="clear()"> close + diff --git a/ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.ts b/ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.ts index e0246cbda3..be8b8d66cb 100644 --- a/ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.ts +++ b/ui-ngx/src/app/modules/home/components/alias/entity-alias-select.component.ts @@ -48,11 +48,11 @@ import { ErrorStateMatcher } from '@angular/material/core'; provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => EntityAliasSelectComponent), multi: true - }, + }/*, { provide: ErrorStateMatcher, useExisting: EntityAliasSelectComponent - }] + }*/] }) export class EntityAliasSelectComponent implements ControlValueAccessor, OnInit, AfterViewInit, ErrorStateMatcher { @@ -237,16 +237,19 @@ export class EntityAliasSelectComponent implements ControlValueAccessor, OnInit, } } - createEntityAlias($event: Event, alias: string) { + createEntityAlias($event: Event, alias: string, focusOnCancel = true) { $event.preventDefault(); + $event.stopPropagation(); this.creatingEntityAlias = true; if (this.callbacks && this.callbacks.createEntityAlias) { this.callbacks.createEntityAlias(alias, this.allowedEntityTypes).subscribe((newAlias) => { if (!newAlias) { - setTimeout(() => { - this.entityAliasInput.nativeElement.blur(); - this.entityAliasInput.nativeElement.focus(); - }, 0); + if (focusOnCancel) { + setTimeout(() => { + this.entityAliasInput.nativeElement.blur(); + this.entityAliasInput.nativeElement.focus(); + }, 0); + } } else { this.entityAliasList.push(newAlias); this.modelValue = newAlias.id; diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts index 8f599d8715..0aad7e7508 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.ts @@ -39,7 +39,7 @@ export interface AddWidgetDialogData { @Component({ selector: 'tb-add-widget-dialog', templateUrl: './add-widget-dialog.component.html', - providers: [{provide: ErrorStateMatcher, useExisting: AddWidgetDialogComponent}], + providers: [/*{provide: ErrorStateMatcher, useExisting: AddWidgetDialogComponent}*/], styleUrls: [] }) export class AddWidgetDialogComponent extends DialogComponent @@ -117,7 +117,7 @@ export class AddWidgetDialogComponent extends DialogComponent close + diff --git a/ui-ngx/src/app/modules/home/components/filter/filter-select.component.ts b/ui-ngx/src/app/modules/home/components/filter/filter-select.component.ts index 8867f554f7..6c844e4a9b 100644 --- a/ui-ngx/src/app/modules/home/components/filter/filter-select.component.ts +++ b/ui-ngx/src/app/modules/home/components/filter/filter-select.component.ts @@ -226,16 +226,19 @@ export class FilterSelectComponent implements ControlValueAccessor, OnInit, Afte } } - createFilter($event: Event, filter: string) { + createFilter($event: Event, filter: string, focusOnCancel = true) { $event.preventDefault(); + $event.stopPropagation(); this.creatingFilter = true; if (this.callbacks && this.callbacks.createFilter) { this.callbacks.createFilter(filter).subscribe((newFilter) => { if (!newFilter) { - setTimeout(() => { - this.filterInput.nativeElement.blur(); - this.filterInput.nativeElement.focus(); - }, 0); + if (focusOnCancel) { + setTimeout(() => { + this.filterInput.nativeElement.blur(); + this.filterInput.nativeElement.focus(); + }, 0); + } } else { this.filterList.push(newFilter); this.modelValue = newFilter.id; diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index 97af82981c..5789c6ff5c 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -181,6 +181,8 @@ import { AlarmAssigneeSelectPanelComponent } from '@home/components/alarm/alarm- import { AlarmAssigneeSelectComponent } from '@home/components/alarm/alarm-assignee-select.component'; import { DeviceInfoFilterComponent } from '@home/components/device/device-info-filter.component'; import { WidgetPreviewComponent } from '@home/components/widget/widget-preview.component'; +import { DatasourceComponent } from '@home/components/widget/datasource.component'; +import { DatasourcesComponent } from '@home/components/widget/datasources.component'; @NgModule({ declarations: @@ -226,6 +228,8 @@ import { WidgetPreviewComponent } from '@home/components/widget/widget-preview.c EntityFilterComponent, EntityAliasSelectComponent, DataKeysComponent, + DatasourceComponent, + DatasourcesComponent, DataKeyConfigComponent, DataKeyConfigDialogComponent, ManageWidgetActionsComponent, @@ -376,6 +380,8 @@ import { WidgetPreviewComponent } from '@home/components/widget/widget-preview.c EntityFilterComponent, EntityAliasSelectComponent, DataKeysComponent, + DatasourceComponent, + DatasourcesComponent, DataKeyConfigComponent, DataKeyConfigDialogComponent, ManageWidgetActionsComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.html b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.html index 0230c4ae08..8d943d5b31 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.html @@ -15,85 +15,92 @@ limitations under the License. --> - - + + {{placeholder}} +
- - +
+
-
-
- drag_handle -
-
-
+
+ drag_indicator
- notifications - - - timeline - {{key.label}} + {{key.label}}
-
:
+
:
+
+
+
+
+
+ - close
- @@ -162,7 +169,7 @@ {{ requiredText }} -
+
{{ maxDataKeysText() }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss index a0b909af1a..3013bf78ae 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss @@ -28,6 +28,13 @@ line-height: 20px; height: 32px; + &.mdc-evolution-chip--with-trailing-action { + .mdc-evolution-chip__action--primary { + padding-left: 4px; + padding-right: 12px; + } + } + .mat-mdc-chip-action { overflow: hidden; .mat-mdc-chip-action-label { @@ -37,15 +44,12 @@ .tb-attribute-chip { max-width: 100%; color: rgb(66, 66, 66); - font-weight: normal; - font-size: 16px; .tb-chip-drag-handle { + padding: 3px; + height: 24px; cursor: move; mat-icon { pointer-events: none; - margin-right: 4px; - margin-left: 4px; - vertical-align: bottom; } } .tb-chip-labels { @@ -53,7 +57,13 @@ flex-direction: row; align-items: center; min-width: 0; + background: rgba(0, 0, 0, 0.04); + border-radius: 100px; + padding: 2px 10px; .tb-chip-label { + font-weight: normal; + font-size: 14px; + line-height: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -70,15 +80,9 @@ white-space: pre; } } - .mat-mdc-chip-remove.mat-icon { - width: 24px; - min-width: 24px; - height: 24px; - font-size: 24px; - margin-right: 4px; + .mat-mdc-chip-remove.mat-mdc-icon-button { color: inherit; opacity: inherit; - padding-left: 0; } } diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts index 23051d78ad..71b4121c9b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts @@ -30,13 +30,14 @@ import { ViewEncapsulation } from '@angular/core'; import { + AbstractControl, ControlValueAccessor, FormGroupDirective, NG_VALUE_ACCESSOR, NgForm, UntypedFormBuilder, UntypedFormControl, - UntypedFormGroup, + UntypedFormGroup, ValidationErrors, Validators } from '@angular/forms'; import { Observable, of } from 'rxjs'; @@ -44,7 +45,7 @@ import { filter, map, mergeMap, publishReplay, refCount, share, tap } from 'rxjs import { Store } from '@ngrx/store'; import { AppState } from '@app/core/core.state'; import { TranslateService } from '@ngx-translate/core'; -import { MatAutocomplete } from '@angular/material/autocomplete'; +import { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete'; import { MatChipGrid, MatChipInputEvent, MatChipRow } from '@angular/material/chips'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; @@ -61,11 +62,12 @@ import { DataKeyConfigDialogComponent, DataKeyConfigDialogData } from '@home/components/widget/data-key-config-dialog.component'; -import { deepClone, guid, isUndefined } from '@core/utils'; +import { deepClone, guid, isDefinedAndNotNull, isUndefined } from '@core/utils'; import { Dashboard } from '@shared/models/dashboard.models'; import { AggregationType } from '@shared/models/time/time.models'; import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive'; import { moveItemInArray } from '@angular/cdk/drag-drop'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-data-keys', @@ -76,11 +78,11 @@ import { moveItemInArray } from '@angular/cdk/drag-drop'; provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DataKeysComponent), multi: true - }, + } /*, { provide: ErrorStateMatcher, useExisting: DataKeysComponent - } + } */ ], encapsulation: ViewEncapsulation.None }) @@ -113,6 +115,10 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange @Input() optDataKeys: boolean; + @Input() + @coerceBoolean() + simpleDataKeysLabel = false; + @Input() aliasController: IAliasController; @@ -148,6 +154,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange @ViewChild('keyInput') keyInput: ElementRef; @ViewChild('keyAutocomplete') matAutocomplete: MatAutocomplete; + @ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger; @ViewChild('chipList') chipList: MatChipGrid; keys: Array = []; @@ -189,10 +196,19 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange } updateValidators() { - this.keysListFormGroup.get('keys').setValidators(this.required ? [Validators.required] : []); + this.keysListFormGroup.get('keys').setValidators(this.required ? [this.keysRequired] : []); this.keysListFormGroup.get('keys').updateValueAndValidity(); } + keysRequired(control: AbstractControl): ValidationErrors | null { + const value = control.value; + if (value && Array.isArray(value) && value.length) { + return null; + } else { + return {required: true}; + } + } + registerOnChange(fn: any): void { this.propagateChange = fn; } @@ -202,7 +218,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange ngOnInit() { this.keysListFormGroup = this.fb.group({ - keys: [null, this.required ? [Validators.required] : []], + keys: [null, this.required ? [this.keysRequired] : []], key: [null] }); this.alarmKeys = []; @@ -251,37 +267,40 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange } private updateParams() { - if (this.datasourceType === DatasourceType.function) { - this.dataKeyType = DataKeyType.function; - this.requiredText = this.translate.instant('datakey.function-types-required'); - if (this.widgetType === widgetType.latest) { - this.placeholder = this.translate.instant('datakey.latest-key-functions'); - this.secondaryPlaceholder = '+' + this.translate.instant('datakey.latest-key-function'); - } else if (this.widgetType === widgetType.alarm) { - this.placeholder = this.translate.instant('datakey.alarm-key-functions'); - this.secondaryPlaceholder = '+' + this.translate.instant('datakey.alarm-key-function'); - } else { - this.placeholder = this.translate.instant('datakey.timeseries-key-functions'); - this.secondaryPlaceholder = '+' + this.translate.instant('datakey.timeseries-key-function'); - } + const singleKey = this.maxDataKeysSet && this.maxDataKeys === 1; + this.secondaryPlaceholder = '+' + this.translate.instant('action.add'); + if (this.datasourceType === DatasourceType.function) { + this.dataKeyType = DataKeyType.function; + this.requiredText = this.translate.instant('datakey.function-types-required'); + if (this.widgetType === widgetType.latest) { + this.placeholder = this.translate.instant(singleKey ? 'datakey.latest-key-function' : 'datakey.latest-key-functions'); + } else if (this.widgetType === widgetType.alarm) { + this.placeholder = this.translate.instant(singleKey ? 'datakey.alarm-key-function' : 'datakey.alarm-key-functions'); + } else { + this.placeholder = this.translate.instant(singleKey ? 'datakey.timeseries-key-function' : 'datakey.timeseries-key-functions'); + } + } else { + if (this.widgetType !== widgetType.latest && this.widgetType !== widgetType.alarm) { + this.dataKeyType = DataKeyType.timeseries; + } else { + this.dataKeyType = null; + } + if (this.simpleDataKeysLabel && this.widgetType !== widgetType.alarm) { + this.placeholder = this.translate.instant(singleKey ? 'datakey.data-key' : 'datakey.data-keys'); + this.requiredText = this.translate.instant(singleKey ? 'datakey.data-key-required' : 'datakey.data-keys-required'); } else { if (this.widgetType === widgetType.latest) { - this.dataKeyType = null; - this.placeholder = this.translate.instant('datakey.latest-keys'); - this.secondaryPlaceholder = '+' + this.translate.instant('datakey.latest-key'); + this.placeholder = this.translate.instant(singleKey ? 'datakey.latest-key' : 'datakey.latest-keys'); this.requiredText = this.translate.instant('datakey.timeseries-or-attributes-required'); } else if (this.widgetType === widgetType.alarm) { - this.dataKeyType = null; - this.placeholder = this.translate.instant('datakey.alarm-keys'); - this.secondaryPlaceholder = '+' + this.translate.instant('datakey.alarm-key'); + this.placeholder = this.translate.instant(singleKey ? 'datakey.alarm-key' : 'datakey.alarm-keys'); this.requiredText = this.translate.instant('datakey.alarm-fields-timeseries-or-attributes-required'); } else { - this.dataKeyType = DataKeyType.timeseries; - this.placeholder = this.translate.instant('datakey.timeseries-keys'); - this.secondaryPlaceholder = '+' + this.translate.instant('datakey.timeseries-key'); + this.placeholder = this.translate.instant(singleKey ? 'datakey.timeseries-key' : 'datakey.timeseries-keys'); this.requiredText = this.translate.instant('datakey.timeseries-required'); } } + } } private reset() { @@ -310,13 +329,13 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange if (propName === 'entityAliasId') { this.clearSearchCache(); this.dirty = true; - } else if (['widgetType', 'datasourceType'].includes(propName)) { + } else if (['widgetType', 'datasourceType', 'maxDataKeys', 'simpleDataKeysLabel'].includes(propName)) { this.clearSearchCache(); this.updateParams(); setTimeout(() => { this.reset(); }, 1); - } else if (['required', 'optDataKeys'].includes('propName')) { + } else if (['required', 'optDataKeys'].includes(propName)) { this.updateValidators(); } } @@ -325,7 +344,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { const originalErrorState = this.errorStateMatcher.isErrorState(control, form); - const customErrorState = this.required && !this.modelValue; + const customErrorState = this.required && (!this.modelValue || !this.modelValue.length); return originalErrorState || customErrorState; } @@ -365,7 +384,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange } addKey(key: DataKey): void { - if (!this.maxDataKeys || this.maxDataKeys < 0 || + if (!this.maxDataKeysSet || !this.modelValue || this.modelValue.length < this.maxDataKeys) { if (!this.modelValue) { this.modelValue = []; @@ -375,17 +394,17 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange this.keysListFormGroup.get('keys').setValue(this.keys); } this.propagateChange(this.modelValue); - this.clear(); + const focus = !this.maxDataKeysSet || this.modelValue.length < this.maxDataKeys; + this.clear('', focus); } add(event: MatChipInputEvent): void { const value = event.value; - if ((value || '').trim()) { - if (this.dataKeyType) { - this.addFromChipValue({name: value.trim(), type: this.dataKeyType}); - } + if ((value || '').trim() && this.dataKeyType) { + this.addFromChipValue({name: value.trim(), type: this.dataKeyType}); + } else { + this.clear(); } - this.clear(); } remove(key: DataKey) { @@ -402,8 +421,10 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange } } - chipDragStart(index: number, chipRow: MatChipRow, placeholderChipRow: MatChipRow) { - this.renderer.setStyle(placeholderChipRow._elementRef.nativeElement, 'width', chipRow._elementRef.nativeElement.offsetWidth + 'px'); + chipDragStart(index: number, chipRow: MatChipRow, placeholderChipRow: Element) { + this.autocomplete.closePanel(); + this.renderer.setStyle(placeholderChipRow, + 'width', chipRow._elementRef.nativeElement.offsetWidth + 'px'); this.dragIndex = index; } @@ -523,22 +544,37 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange } textIsNotEmpty(text: string): boolean { - return (text && text != null && text.length > 0) ? true : false; + return text && text.length > 0; } - clear(value: string = '') { + clear(value: string = '', focus = true) { + this.autocomplete.closePanel(); this.keyInput.nativeElement.value = value; - this.keysListFormGroup.get('key').patchValue(value, {emitEvent: true}); - setTimeout(() => { - this.keyInput.nativeElement.blur(); - this.keyInput.nativeElement.focus(); - }, 0); + this.keysListFormGroup.get('key').patchValue(value, {emitEvent: focus}); + if (focus) { + setTimeout(() => { + this.keyInput.nativeElement.blur(); + this.keyInput.nativeElement.focus(); + }, 0); + } } get isCountDatasource(): boolean { return [DatasourceType.entityCount, DatasourceType.alarmCount].includes(this.datasourceType); } + get inputDisabled(): boolean { + return this.isCountDatasource || (this.maxDataKeysSet && this.keys.length >= this.maxDataKeys); + } + + get dragDisabled(): boolean { + return this.keys.length < 2; + } + + get maxDataKeysSet(): boolean { + return isDefinedAndNotNull(this.maxDataKeysValue) && this.maxDataKeysValue > -1; + } + private clearSearchCache() { this.searchText = ''; this.fetchObservable$ = null; diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.html b/ui-ngx/src/app/modules/home/components/widget/datasource.component.html new file mode 100644 index 0000000000..797415e687 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/datasource.component.html @@ -0,0 +1,95 @@ + +
+ + widget-config.datasource-type + + + {{ datasourceTypesTranslations.get(datasourceType) | translate }} + + + +
+ + + datasource.label + + + + + + + + + + + + + +
+
+ + + + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/datasource.component.models.ts new file mode 100644 index 0000000000..208cdd7b47 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/datasource.component.models.ts @@ -0,0 +1,21 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { EntityAliasSelectCallbacks } from '@home/components/alias/entity-alias-select.component.models'; +import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models'; +import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; + +export type DatasourceCallbacks = EntityAliasSelectCallbacks & FilterSelectCallbacks & DataKeysCallbacks; diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.scss b/ui-ngx/src/app/modules/home/components/widget/datasource.component.scss new file mode 100644 index 0000000000..163e74d336 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/datasource.component.scss @@ -0,0 +1,33 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-datasource-section { + display: flex; + flex-direction: column; + align-items: stretch; + flex: 1; +} + +:host ::ng-deep { + .tb-datasource-section { + tb-alarm-filter-config { + .mdc-button { + width: 100%; + height: 100%; + justify-content: flex-start; + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts b/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts new file mode 100644 index 0000000000..1d6053e024 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts @@ -0,0 +1,243 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + Validator, + Validators +} from '@angular/forms'; +import { + Datasource, + DatasourceType, + datasourceTypeTranslationMap, + JsonSettingsSchema, + Widget, + widgetType +} from '@shared/models/widget.models'; +import { AlarmSearchStatus } from '@shared/models/alarm.models'; +import { Dashboard } from '@shared/models/dashboard.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { IAliasController } from '@core/api/widget-api.models'; +import { EntityAliasSelectCallbacks } from '@home/components/alias/entity-alias-select.component.models'; +import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models'; +import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; + +@Component({ + selector: 'tb-datasource', + templateUrl: './datasource.component.html', + styleUrls: ['./datasource.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => DatasourceComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => DatasourceComponent), + multi: true, + } + ] +}) +export class DatasourceComponent implements ControlValueAccessor, OnInit, Validator { + + public get widgetType(): widgetType { + return this.widgetConfigComponent.widgetType; + } + + public get aliasController(): IAliasController { + return this.widgetConfigComponent.aliasController; + } + + public get entityAliasSelectCallbacks(): EntityAliasSelectCallbacks { + return this.widgetConfigComponent.widgetConfigCallbacks; + } + + public get filterSelectCallbacks(): FilterSelectCallbacks { + return this.widgetConfigComponent.widgetConfigCallbacks; + } + + public get dataKeysCallbacks(): DataKeysCallbacks { + return this.widgetConfigComponent.widgetConfigCallbacks; + } + + public get hasAdditionalLatestDataKeys(): boolean { + return this.widgetConfigComponent.widgetType === widgetType.timeseries && + this.widgetConfigComponent.modelValue?.typeParameters?.hasAdditionalLatestDataKeys; + } + + public get dataKeysOptional(): boolean { + return this.widgetConfigComponent.modelValue?.typeParameters?.dataKeysOptional; + } + + public get maxDataKeys(): number { + return this.widgetConfigComponent.modelValue?.typeParameters?.maxDataKeys; + } + + public get dataKeySettingsSchema(): JsonSettingsSchema { + return this.widgetConfigComponent.modelValue?.dataKeySettingsSchema; + } + + public get dataKeySettingsDirective(): string { + return this.widgetConfigComponent.modelValue?.dataKeySettingsDirective; + } + + public get latestDataKeySettingsSchema(): JsonSettingsSchema { + return this.widgetConfigComponent.modelValue?.latestDataKeySettingsSchema; + } + + public get latestDataKeySettingsDirective(): string { + return this.widgetConfigComponent.modelValue?.latestDataKeySettingsDirective; + } + + public get dashboard(): Dashboard { + return this.widgetConfigComponent.dashboard; + } + + public get widget(): Widget { + return this.widgetConfigComponent.widget; + } + + @Input() + disabled: boolean; + + widgetTypes = widgetType; + + datasourceType = DatasourceType; + datasourceTypes: Array = []; + datasourceTypesTranslations = datasourceTypeTranslationMap; + + datasourceFormGroup: UntypedFormGroup; + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder, + private widgetConfigComponent: WidgetConfigComponent) { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + if (!this.datasourceFormGroup.valid) { + setTimeout(() => { + this.datasourceUpdated(this.datasourceFormGroup.value); + }, 0); + } + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.datasourceFormGroup.disable({emitEvent: false}); + } else { + this.datasourceFormGroup.enable({emitEvent: false}); + this.updateValidators(); + } + } + + ngOnInit() { + if (this.widgetConfigComponent.functionsOnly) { + this.datasourceTypes = [DatasourceType.function]; + } else { + this.datasourceTypes = [DatasourceType.function, DatasourceType.entity]; + if (this.widgetConfigComponent.widgetType === widgetType.latest) { + this.datasourceTypes.push(DatasourceType.entityCount); + this.datasourceTypes.push(DatasourceType.alarmCount); + } + } + + this.datasourceFormGroup = this.fb.group( + { + type: [null, [Validators.required]], + name: [null, []], + entityAliasId: [null, []], + filterId: [null, []], + dataKeys: [null, []], + alarmFilterConfig: [null, []] + } + ); + if (this.hasAdditionalLatestDataKeys) { + this.datasourceFormGroup.addControl('latestDataKeys', this.fb.control(null)); + } + this.datasourceFormGroup.get('type').valueChanges.subscribe(() => { + this.updateValidators(); + }); + this.datasourceFormGroup.valueChanges.subscribe( + () => { + this.datasourceUpdated(this.datasourceFormGroup.value); + } + ); + } + + writeValue(datasource?: Datasource): void { + this.datasourceFormGroup.patchValue({ + type: datasource?.type, + name: datasource?.name, + entityAliasId: datasource?.entityAliasId, + filterId: datasource?.filterId, + dataKeys: datasource?.dataKeys, + alarmFilterConfig: datasource?.alarmFilterConfig ? + datasource?.alarmFilterConfig : { statusList: [AlarmSearchStatus.ACTIVE] } + }, {emitEvent: false}); + if (this.hasAdditionalLatestDataKeys) { + this.datasourceFormGroup.patchValue({ + latestDataKeys: datasource?.latestDataKeys + }, {emitEvent: false}); + } + this.updateValidators(); + } + + validate(c: UntypedFormControl) { + return (this.datasourceFormGroup.valid) ? null : { + datasource: { + valid: false, + }, + }; + } + + public isDataKeysOptional(type?: DatasourceType): boolean { + if (this.hasAdditionalLatestDataKeys) { + return true; + } else { + return this.dataKeysOptional + && type !== DatasourceType.entityCount && type !== DatasourceType.alarmCount; + } + } + + private datasourceUpdated(datasource: Datasource) { + this.propagateChange(datasource); + } + + private updateValidators() { + const type: DatasourceType = this.datasourceFormGroup.get('type').value; + this.datasourceFormGroup.get('entityAliasId').setValidators( + (type === DatasourceType.entity || type === DatasourceType.entityCount) ? [Validators.required] : [] + ); + const newDataKeysRequired = !this.isDataKeysOptional(type); + this.datasourceFormGroup.get('dataKeys').setValidators(newDataKeysRequired ? [Validators.required] : []); + this.datasourceFormGroup.get('entityAliasId').updateValueAndValidity({emitEvent: false}); + this.datasourceFormGroup.get('dataKeys').updateValueAndValidity({emitEvent: false}); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.html b/ui-ngx/src/app/modules/home/components/widget/datasources.component.html new file mode 100644 index 0000000000..ef109765b0 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/datasources.component.html @@ -0,0 +1,89 @@ + +
+
+
+
{{ (singleDatasource ? 'widget-config.datasource' : 'widget-config.datasources') | translate }}
+
+ {{ 'widget-config.timeseries-key-error' | translate }} +
+
+
{{ 'widget-config.maximum-datasources' | translate:{count: maxDatasources} }}
+
+
+ datasource.add-datasource-prompt +
+ +
+ + +
+
+
{{$index + 1}}
+
+
+
+ + +
+ + +
+
+ +
+
+
+
+
+
+
+ +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.scss b/ui-ngx/src/app/modules/home/components/widget/datasources.component.scss new file mode 100644 index 0000000000..8be2eeadbf --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/datasources.component.scss @@ -0,0 +1,83 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@import "../../../../../theme"; + +.tb-datasource-list-item { + &.mat-mdc-list-item { + height: auto; + display: block; + padding: 0; + &.bordered { + padding-top: 16px; + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 6px; + } + } + &.tb-draggable { + &.cdk-drag-preview { + background: #fff; + } + } +} + +.tb-datasource-list-item + .tb-datasource-list-item { + margin-top: 16px; +} + +.tb-datasource-index { + width: 24px; + height: 24px; + position: relative; + font-weight: 400; + font-size: 16px; + text-align: center; + color: $tb-primary-color; + &:before { + content: ""; + display: block; + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background-color: $tb-primary-color; + opacity: 0.06; + border-radius: 100%; + } +} + +.tb-datasource-params { + position: relative; + tb-error.tb-datasource-error { + position: absolute; + bottom: 4px; + left: 8px; + } +} + +:host { + .tb-datasources { + + .handle { + cursor: move; + } + + .mat-mdc-list { + min-height: 68px; + padding-left: 0; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts b/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts new file mode 100644 index 0000000000..7c1196a0c4 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts @@ -0,0 +1,236 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + AbstractControl, + ControlValueAccessor, FormControl, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, UntypedFormArray, + UntypedFormBuilder, UntypedFormControl, + UntypedFormGroup, + Validator +} from '@angular/forms'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { Datasource, DatasourceType, JsonSettingsSchema, widgetType } from '@shared/models/widget.models'; +import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { deepClone } from '@core/utils'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { UtilsService } from '@core/services/utils.service'; +import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; + +@Component({ + selector: 'tb-datasources', + templateUrl: './datasources.component.html', + styleUrls: ['./datasources.component.scss', 'widget-config.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => DatasourcesComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => DatasourcesComponent), + multi: true, + } + ] +}) +export class DatasourcesComponent implements ControlValueAccessor, OnInit, Validator { + + public get maxDatasources(): number { + return this.widgetConfigComponent.modelValue?.typeParameters?.maxDatasources; + } + + public get singleDatasource(): boolean { + return this.maxDatasources === 1; + } + + public get showAddDatasource(): boolean { + return this.widgetConfigComponent.modelValue?.typeParameters && + (this.maxDatasources === -1 || this.datasourcesFormArray.length < this.maxDatasources); + } + + public get dragDisabled(): boolean { + return this.disabled || this.singleDatasource || this.datasourcesFormArray.length < 2; + } + + @Input() + disabled: boolean; + + datasourcesFormGroup: UntypedFormGroup; + + timeseriesKeyError = false; + + datasourceError: string[] = []; + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder, + private utils: UtilsService, + private widgetConfigComponent: WidgetConfigComponent) { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + if (this.validate(null)) { + setTimeout(() => { + this.datasourcesUpdated(this.datasourcesFormGroup.get('datasources').value); + }, 0); + } + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.datasourcesFormGroup.disable({emitEvent: false}); + } else { + this.datasourcesFormGroup.enable({emitEvent: false}); + } + } + + ngOnInit() { + this.datasourcesFormGroup = this.fb.group({ + datasources: this.fb.array([]) + }); + this.datasourcesFormGroup.valueChanges.subscribe( + () => { + this.datasourcesUpdated(this.datasourcesFormGroup.get('datasources').value); + } + ); + } + + writeValue(datasources?: Datasource[]): void { + this.datasourcesFormArray.clear({emitEvent: false}); + if (datasources) { + datasources.forEach((datasource) => { + this.datasourcesFormArray.push(this.fb.control(datasource, []), {emitEvent: false}); + }); + } + if (this.singleDatasource && !this.datasourcesFormArray.length) { + this.addDatasource(false); + } + } + + validate(c: UntypedFormControl) { + this.timeseriesKeyError = false; + this.datasourceError = []; + if (!this.datasourcesFormGroup.valid) { + return { + datasources: { + valid: false, + } + }; + } + const datasources: Datasource[] = this.datasourcesFormGroup.get('datasources').value; + if (!this.datasourcesOptional && (!datasources || !datasources.length)) { + return { + datasources: { + valid: false + } + }; + } + if (this.hasAdditionalLatestDataKeys) { + let valid = datasources.filter(datasource => datasource?.dataKeys?.length).length > 0; + if (!valid) { + this.timeseriesKeyError = true; + return { + timeseriesDataKeys: { + valid: false + } + }; + } else { + const emptyDatasources = datasources.filter(datasource => !datasource?.dataKeys?.length && + !datasource?.latestDataKeys?.length); + valid = emptyDatasources.length === 0; + if (!valid) { + for (const emptyDatasource of emptyDatasources) { + const i = datasources.indexOf(emptyDatasource); + this.datasourceError[i] = 'At least one data key should be specified'; + } + return { + dataKeys: { + valid: false + } + }; + } + } + } + return null; + } + + get datasourcesFormArray(): UntypedFormArray { + return this.datasourcesFormGroup.get('datasources') as UntypedFormArray; + } + + get datasourcesControls(): FormControl[] { + return this.datasourcesFormArray.controls as FormControl[]; + } + + public trackByDatasource(index: number, datasourceControl: AbstractControl): any { + return datasourceControl; + } + + private datasourcesUpdated(datasources: Datasource[]) { + this.propagateChange(datasources); + } + + public onDatasourceDrop(event: CdkDragDrop) { + const datasourceForm = this.datasourcesFormArray.at(event.previousIndex); + this.datasourcesFormArray.removeAt(event.previousIndex); + this.datasourcesFormArray.insert(event.currentIndex, datasourceForm); + } + + public removeDatasource(index: number) { + this.datasourcesFormArray.removeAt(index); + } + + public addDatasource(emitEvent = true) { + let newDatasource: Datasource; + if (this.widgetConfigComponent.functionsOnly) { + newDatasource = deepClone(this.utils.getDefaultDatasource(this.dataKeySettingsSchema.schema)); + newDatasource.dataKeys = [this.dataKeysCallbacks.generateDataKey('Sin', DataKeyType.function, this.dataKeySettingsSchema)]; + } else { + newDatasource = { type: DatasourceType.entity, + dataKeys: [] + }; + } + if (this.hasAdditionalLatestDataKeys) { + newDatasource.latestDataKeys = []; + } + this.datasourcesFormArray.push(this.fb.control(newDatasource, []), {emitEvent}); + } + + private get dataKeySettingsSchema(): JsonSettingsSchema { + return this.widgetConfigComponent.modelValue?.dataKeySettingsSchema; + } + + private get dataKeysCallbacks(): DataKeysCallbacks { + return this.widgetConfigComponent.widgetConfigCallbacks; + } + + private get hasAdditionalLatestDataKeys(): boolean { + return this.widgetConfigComponent.widgetType === widgetType.timeseries && + this.widgetConfigComponent.modelValue?.typeParameters?.hasAdditionalLatestDataKeys; + } + + private get datasourcesOptional(): boolean { + return this.widgetConfigComponent.modelValue?.typeParameters?.datasourcesOptional; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html index f2e2a0e8ba..dfc9feeb60 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html @@ -23,313 +23,104 @@
-
-
-
- - {{ 'widget-config.use-dashboard-timewindow' | translate }} - - - {{ 'widget-config.display-timewindow' | translate }} - +
+
+
+
timewindow.timewindow
+ +
-
- widget-config.timewindow +
-
+ formControlName="timewindow"> + + {{ 'widget-config.display-timewindow' | translate }} + +
-
+
- - - - -
-
widget-config.datasources
-
{{ 'widget-config.maximum-datasources' | translate:{count: modelValue?.typeParameters.maxDatasources} }}
-
- - report_gmailerrorred - -
- - {{ 'widget-config.timeseries-key-error' | translate }} - -
-
- datasource.add-datasource-prompt -
- -
- -
- widget-config.datasource-type - widget-config.datasource-parameters - -
-
-
- - -
-
- - {{$index + 1}}. -
-
-
-
- - - - {{ datasourceTypesTranslations.get(datasourceType) | translate }} - - - -
- - - datasource.label - - - - - - - - - - - - - -
-
- - - - -
-
- -
- -
-
-
-
- -
-
-
- -
-
- - - - {{ 'widget-config.target-device' | translate }} - - -
- - -
-
- - - - {{ 'widget-config.alarm-source' | translate }} - - -
-
- - - - {{ datasourceTypesTranslations.get(datasourceType) | translate }} - - - -
- - - - - - -
- - -
-
-
- - - widget-config.data-settings - - -
- - widget-config.data-page-size - - -
-
- - widget-config.units - - - - widget-config.decimals - - -
-
- - widget-config.no-data-display-message - - -
-
-
-
+ + +
+
widget-config.target-device
+
+ + +
+
+
+
widget-config.alarm-source
+ + +
+
+
widget-config.limits
+
+
widget-config.data-page-size
+ + + +
+
-
- - +
+
+
widget-config.data-settings
+
+
widget-config.units
+ + + +
+
+
widget-config.decimals
+ + + +
+
+
widget-config.no-data-display-message
+ + + +
+
+
+ + +
-
-
- widget-config.title +
+
+
widget-config.card-title
{{ 'widget-config.display-title' | translate }} @@ -343,31 +134,28 @@
-
- widget-config.title-icon +
{{ 'widget-config.display-icon' | translate }} -
- +
+ - - - - widget-config.icon-size + + + +
-
+
- - - widget-config.advanced-settings + + + widget-config.advanced-title-style @@ -379,45 +167,46 @@ > -
-
- widget-config.widget-style -
-
- - - +
+
widget-config.card-style
+
+
{{ 'widget-config.text' | translate }}
+
+ +
-
- - widget-config.padding - - - - widget-config.margin - - +
+
+
{{ 'widget-config.background' | translate }}
+
+ + +
- +
+
{{ 'widget-config.padding' | translate }}
+ + + +
+
+
{{ 'widget-config.margin' | translate }}
+ + + +
+ {{ 'widget-config.drop-shadow' | translate }} - - {{ 'widget-config.enable-fullscreen' | translate }} - - - widget-config.advanced-settings + + widget-config.advanced-widget-style @@ -433,31 +222,45 @@ > -
+
+
+
widget-config.card-buttons
+ + {{ 'widget-config.enable-fullscreen' | translate }} + +
-
+
-
- - {{ 'widget-config.mobile-hide' | translate }} - - - {{ 'widget-config.desktop-hide' | translate }} - -
- - widget-config.order - - - - widget-config.height - - +
+
+ + {{ 'widget-config.mobile-hide' | translate }} + +
+
+ + {{ 'widget-config.desktop-hide' | translate }} + +
+
+
+
widget-config.order
+ + + +
+
+
widget-config.height
+ + + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts index e8a7e24c63..7a141f6e75 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts @@ -14,9 +14,7 @@ /// limitations under the License. /// -import { EntityAliasSelectCallbacks } from '../alias/entity-alias-select.component.models'; -import { DataKeysCallbacks } from './data-keys.component.models'; import { WidgetActionCallbacks } from './action/manage-widget-actions.component.models'; -import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models'; +import { DatasourceCallbacks } from '@home/components/widget/datasource.component.models'; -export type WidgetConfigCallbacks = EntityAliasSelectCallbacks & FilterSelectCallbacks & DataKeysCallbacks & WidgetActionCallbacks; +export type WidgetConfigCallbacks = DatasourceCallbacks & WidgetActionCallbacks; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss index e3926c8eea..786456dacf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +@import "../../../../../theme"; @import '../../../../../scss/constants'; .tb-widget-config { @@ -33,105 +35,10 @@ & > div { padding: 16px; } - } - .tb-panel-hint { - font-size: 12px; - color: #808080; - } -} - -.tb-datasource-list-item { - &.mat-mdc-list-item { - height: auto; - min-height: 68px; - display: block; - padding: 0; - } - &.tb-draggable { - &.cdk-drag-preview { - background: #fff; - } - } -} - -.tb-datasource-params { - position: relative; - padding: 0 0 0 10px; - margin: 5px; - tb-error.tb-datasource-error { - position: absolute; - bottom: 4px; - left: 8px; - } - .tb-datasource-section { - display: flex; - flex-direction: column; - align-items: stretch; - flex: 1; - padding-top: 20px; - @media #{$mat-gt-sm} { - flex-direction: row; - align-items: center; - justify-content: flex-start; - } - } - .tb-datasource-type { - min-width: 160px; - @media #{$mat-gt-sm} { - max-width: 160px; - } - } - .tb-datasource { - @media #{$mat-gt-sm} { - padding-left: 8px; - width: 208px; - max-width: 208px; - } - } - .tb-data-keys { - @media #{$mat-gt-sm} { - padding-left: 8px; - } - } -} - -:host { - .tb-widget-config { - .tb-advanced-widget-config { - height: 100%; - } - .tb-datasources { - - .handle { - cursor: move; - } - - .mat-mdc-list { - min-height: 68px; - padding-left: 0; - } - } - .fields-group { - padding: 0 16px 8px; - margin-bottom: 10px; - border: 1px groove rgba(0, 0, 0, .25); - border-radius: 4px; - legend { - color: rgba(0, 0, 0, .7); - width: fit-content; - } - } - .fields-group-slider { - padding: 0; - legend { - margin-left: 16px; - } - .tb-settings { - padding: 0 16px 8px; - } - } - .tb-widget-style { - margin-top: 16px; + .mat-content { + display: flex; + flex-direction: column; + gap: 16px; } } } @@ -143,13 +50,6 @@ padding: 0 20px; } } - tb-alarm-filter-config { - .mdc-button { - width: 100%; - height: 100%; - justify-content: flex-start; - } - } .mat-mdc-tab-body-wrapper { position: absolute; top: 49px; @@ -157,53 +57,5 @@ right: 0; bottom: 0; } - .mat-expansion-panel { - &.tb-settings { - box-shadow: none; - .mat-content { - overflow: visible; - } - .mat-expansion-panel-header { - padding: 0; - &:hover { - background: none; - } - .mat-expansion-indicator { - padding: 2px; - } - } - .mat-expansion-panel-header-description { - align-items: center; - } - > .mat-expansion-panel-content { - > .mat-expansion-panel-body { - padding: 0; - } - } - .tb-json-object-panel, .tb-css-content-panel { - margin: 0 0 8px; - } - } - &.tb-datasources { - &.mat-expanded { - overflow: visible; - } - .mat-expansion-panel-body{ - padding: 0 12px 16px; - } - } - .mat-expansion-panel-content { - font: inherit; - } - } - .mat-slide { - margin: 8px 0; - } - .slide-block { - display: block; - &:not(:last-child) { - margin-bottom: 8px; - } - } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index 634b893526..cf01244a0c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -20,11 +20,8 @@ import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { DataKey, - Datasource, datasourcesHasAggregation, datasourcesHasOnlyComparisonAggregation, - DatasourceType, - datasourceTypeTranslationMap, GroupInfo, JsonSchema, JsonSettingsSchema, @@ -35,7 +32,6 @@ import { ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, @@ -66,7 +62,6 @@ import { Dashboard } from '@shared/models/dashboard.models'; import { entityFields } from '@shared/models/entity.models'; import { Filter } from '@shared/models/query/query.models'; import { FilterDialogComponent, FilterDialogData } from '@home/components/filter/filter-dialog.component'; -import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { ToggleHeaderOption } from '@shared/components/toggle-header.component'; const emptySettingsSchema: JsonSchema = { @@ -81,7 +76,7 @@ const defaultSettingsForm = [ @Component({ selector: 'tb-widget-config', templateUrl: './widget-config.component.html', - styleUrls: ['./widget-config.component.scss'], + styleUrls: ['./widget-config.component.scss', 'widget-config.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -120,10 +115,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe widgetType: widgetType; - datasourceType = DatasourceType; - datasourceTypes: Array = []; - datasourceTypesTranslations = datasourceTypeTranslationMap; - widgetConfigCallbacks: WidgetConfigCallbacks = { createEntityAlias: this.createEntityAlias.bind(this), createFilter: this.createFilter.bind(this), @@ -143,19 +134,13 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe public dataSettings: UntypedFormGroup; public targetDeviceSettings: UntypedFormGroup; - public alarmSourceSettings: UntypedFormGroup; public widgetSettings: UntypedFormGroup; public layoutSettings: UntypedFormGroup; public advancedSettings: UntypedFormGroup; public actionsSettings: UntypedFormGroup; - public openExtensionPanel = true; - public timeseriesKeyError = false; - - public datasourceError: string[] = []; private dataSettingsChangesSubscription: Subscription; private targetDeviceSettingsSubscription: Subscription; - private alarmSourceSettingsSubscription: Subscription; private widgetSettingsSubscription: Subscription; private layoutSettingsSubscription: Subscription; private advancedSettingsSubscription: Subscription; @@ -165,7 +150,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private utils: UtilsService, private entityService: EntityService, private dialog: MatDialog, - private translate: TranslateService, + public translate: TranslateService, private fb: UntypedFormBuilder) { super(store); } @@ -173,7 +158,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe ngOnInit(): void { this.dataSettings = this.fb.group({}); this.targetDeviceSettings = this.fb.group({}); - this.alarmSourceSettings = this.fb.group({}); this.advancedSettings = this.fb.group({}); this.widgetSettings = this.fb.group({ title: [null, []], @@ -197,30 +181,14 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe decimals: [null, [Validators.min(0), Validators.max(15), Validators.pattern(/^\d*$/)]], noDataDisplayMessage: [null, []] }); - this.widgetSettings.get('showTitle').valueChanges.subscribe((value: boolean) => { - if (value) { - this.widgetSettings.get('titleStyle').enable({emitEvent: false}); - this.widgetSettings.get('titleTooltip').enable({emitEvent: false}); - this.widgetSettings.get('showTitleIcon').enable({emitEvent: false}); - } else { - this.widgetSettings.get('titleStyle').disable({emitEvent: false}); - this.widgetSettings.get('titleTooltip').disable({emitEvent: false}); - this.widgetSettings.get('showTitleIcon').patchValue(false); - this.widgetSettings.get('showTitleIcon').disable({emitEvent: false}); - } - }); - this.widgetSettings.get('showTitleIcon').valueChanges.subscribe((value: boolean) => { - if (value) { - this.widgetSettings.get('titleIcon').enable({emitEvent: false}); - this.widgetSettings.get('iconColor').enable({emitEvent: false}); - this.widgetSettings.get('iconSize').enable({emitEvent: false}); - } else { - this.widgetSettings.get('titleIcon').disable({emitEvent: false}); - this.widgetSettings.get('iconColor').disable({emitEvent: false}); - this.widgetSettings.get('iconSize').disable({emitEvent: false}); - } + this.widgetSettings.get('showTitle').valueChanges.subscribe(() => { + this.updateWidgetSettingsEnabledState(); + }); + this.widgetSettings.get('showTitleIcon').valueChanges.subscribe(() => { + this.updateWidgetSettingsEnabledState(); }); + this.layoutSettings = this.fb.group({ mobileOrder: [null, [Validators.pattern(/^-?[0-9]+$/)]], mobileHeight: [null, [Validators.min(1), Validators.pattern(/^\d*$/)]], @@ -245,10 +213,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.targetDeviceSettingsSubscription.unsubscribe(); this.targetDeviceSettingsSubscription = null; } - if (this.alarmSourceSettingsSubscription) { - this.alarmSourceSettingsSubscription.unsubscribe(); - this.alarmSourceSettingsSubscription = null; - } if (this.widgetSettingsSubscription) { this.widgetSettingsSubscription.unsubscribe(); this.widgetSettingsSubscription = null; @@ -274,9 +238,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.targetDeviceSettingsSubscription = this.targetDeviceSettings.valueChanges.subscribe( () => this.updateTargetDeviceSettings() ); - this.alarmSourceSettingsSubscription = this.alarmSourceSettings.valueChanges.subscribe( - () => this.updateAlarmSourceSettings() - ); this.widgetSettingsSubscription = this.widgetSettings.valueChanges.subscribe( () => this.updateWidgetSettings() ); @@ -291,33 +252,55 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe ); } - private buildForms() { - if (this.functionsOnly) { - this.datasourceTypes = [DatasourceType.function]; - } else { - this.datasourceTypes = [DatasourceType.function, DatasourceType.entity]; - if (this.widgetType === widgetType.latest) { - this.datasourceTypes.push(DatasourceType.entityCount); - this.datasourceTypes.push(DatasourceType.alarmCount); - } + private buildHeader() { + this.headerOptions.length = 0; + if (this.widgetType !== widgetType.static) { + this.headerOptions.push( + { + name: this.translate.instant('widget-config.data'), + value: 'data' + } + ); } + if (this.displayAppearance) { + this.headerOptions.push( + { + name: this.translate.instant('widget-config.appearance'), + value: 'appearance' + } + ); + } + this.headerOptions.push( + { + name: this.translate.instant('widget-config.widget-card'), + value: 'card' + } + ); + this.headerOptions.push( + { + name: this.translate.instant('widget-config.actions'), + value: 'actions' + } + ); + this.headerOptions.push( + { + name: this.translate.instant('widget-config.mobile'), + value: 'mobile' + } + ); + this.selectedOption = this.headerOptions[0].value; + } + private buildForms() { this.dataSettings = this.fb.group({}); this.targetDeviceSettings = this.fb.group({}); - this.alarmSourceSettings = this.fb.group({}); this.advancedSettings = this.fb.group({}); if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) { this.dataSettings.addControl('useDashboardTimewindow', this.fb.control(true)); this.dataSettings.addControl('displayTimewindow', this.fb.control({value: true, disabled: true})); this.dataSettings.addControl('timewindow', this.fb.control({value: null, disabled: true})); - this.dataSettings.get('useDashboardTimewindow').valueChanges.subscribe((value: boolean) => { - if (value) { - this.dataSettings.get('displayTimewindow').disable({emitEvent: false}); - this.dataSettings.get('timewindow').disable({emitEvent: false}); - } else { - this.dataSettings.get('displayTimewindow').enable({emitEvent: false}); - this.dataSettings.get('timewindow').enable({emitEvent: false}); - } + this.dataSettings.get('useDashboardTimewindow').valueChanges.subscribe(() => { + this.updateDataSettingsEnabledState(); }); if (this.widgetType === widgetType.alarm) { this.dataSettings.addControl('alarmFilterConfig', this.fb.control(null)); @@ -327,24 +310,19 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe if (this.widgetType !== widgetType.rpc && this.widgetType !== widgetType.alarm && this.widgetType !== widgetType.static) { - this.dataSettings.addControl('datasources', - this.fb.array([])); + this.dataSettings.addControl('datasources', this.fb.control(null)); } else if (this.widgetType === widgetType.rpc) { this.targetDeviceSettings.addControl('targetDeviceAliasId', this.fb.control(null, this.widgetEditMode ? [] : [Validators.required])); } else if (this.widgetType === widgetType.alarm) { - this.alarmSourceSettings = this.buildDatasourceForm(); + this.dataSettings.addControl('alarmSource', this.fb.control(null)); } } this.advancedSettings.addControl('settings', this.fb.control(null, [])); } - datasourcesFormArray(): UntypedFormArray { - return this.dataSettings.get('datasources') as UntypedFormArray; - } - registerOnChange(fn: any): void { this.propagateChange = fn; } @@ -360,46 +338,11 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.modelValue = value; this.removeChangeSubscriptions(); if (this.modelValue) { - this.headerOptions.length = 0; - if (this.modelValue.widgetType !== widgetType.static) { - this.headerOptions.push( - { - name: this.translate.instant('widget-config.data'), - value: 'data' - } - ); - } - if (this.displayAdvanced()) { - this.headerOptions.push( - { - name: this.translate.instant('widget-config.appearance'), - value: 'appearance' - } - ); - } - this.headerOptions.push( - { - name: this.translate.instant('widget-config.widget-card'), - value: 'card' - } - ); - this.headerOptions.push( - { - name: this.translate.instant('widget-config.actions'), - value: 'actions' - } - ); - this.headerOptions.push( - { - name: this.translate.instant('widget-config.mobile'), - value: 'mobile' - } - ); - this.selectedOption = this.headerOptions[0].value; if (this.widgetType !== this.modelValue.widgetType) { this.widgetType = this.modelValue.widgetType; this.buildForms(); } + this.buildHeader(); const config = this.modelValue.config; const layout = this.modelValue.layout; if (config) { @@ -431,26 +374,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe }, {emitEvent: false} ); - const showTitle: boolean = this.widgetSettings.get('showTitle').value; - if (showTitle) { - this.widgetSettings.get('titleTooltip').enable({emitEvent: false}); - this.widgetSettings.get('titleStyle').enable({emitEvent: false}); - this.widgetSettings.get('showTitleIcon').enable({emitEvent: false}); - } else { - this.widgetSettings.get('titleTooltip').disable({emitEvent: false}); - this.widgetSettings.get('titleStyle').disable({emitEvent: false}); - this.widgetSettings.get('showTitleIcon').disable({emitEvent: false}); - } - const showTitleIcon: boolean = this.widgetSettings.get('showTitleIcon').value; - if (showTitleIcon) { - this.widgetSettings.get('titleIcon').enable({emitEvent: false}); - this.widgetSettings.get('iconColor').enable({emitEvent: false}); - this.widgetSettings.get('iconSize').enable({emitEvent: false}); - } else { - this.widgetSettings.get('titleIcon').disable({emitEvent: false}); - this.widgetSettings.get('iconColor').disable({emitEvent: false}); - this.widgetSettings.get('iconSize').disable({emitEvent: false}); - } + this.updateWidgetSettingsEnabledState(); const actionsData: WidgetActionsData = { actionsMap: config.actions || {}, actionSources: this.modelValue.actionSources || {} @@ -467,13 +391,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.dataSettings.patchValue( { useDashboardTimewindow }, {emitEvent: false} ); - if (useDashboardTimewindow) { - this.dataSettings.get('displayTimewindow').disable({emitEvent: false}); - this.dataSettings.get('timewindow').disable({emitEvent: false}); - } else { - this.dataSettings.get('displayTimewindow').enable({emitEvent: false}); - this.dataSettings.get('timewindow').enable({emitEvent: false}); - } this.dataSettings.patchValue( { displayTimewindow: isDefined(config.displayTimewindow) ? config.displayTimewindow : true }, {emitEvent: false} @@ -481,18 +398,14 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.dataSettings.patchValue( { timewindow: config.timewindow }, {emitEvent: false} ); + this.updateDataSettingsEnabledState(); } if (this.modelValue.isDataEnabled) { if (this.widgetType !== widgetType.rpc && this.widgetType !== widgetType.alarm && this.widgetType !== widgetType.static) { - const datasourcesFormArray = this.dataSettings.get('datasources') as UntypedFormArray; - datasourcesFormArray.clear(); - if (config.datasources) { - config.datasources.forEach((datasource) => { - datasourcesFormArray.push(this.buildDatasourceForm(datasource)); - }); - } + this.dataSettings.patchValue({ datasources: config.datasources}, + {emitEvent: false}); } else if (this.widgetType === widgetType.rpc) { let targetDeviceAliasId: string; if (config.targetDeviceAliasIds && config.targetDeviceAliasIds.length > 0) { @@ -512,16 +425,10 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } else if (this.widgetType === widgetType.alarm) { this.dataSettings.patchValue( { alarmFilterConfig: isDefined(config.alarmFilterConfig) ? - config.alarmFilterConfig : { statusList: [AlarmSearchStatus.ACTIVE], searchPropagatedAlarms: true } }, {emitEvent: false} + config.alarmFilterConfig : + { statusList: [AlarmSearchStatus.ACTIVE], searchPropagatedAlarms: true }, + alarmSource: config.alarmSource }, {emitEvent: false} ); - this.alarmSourceSettings.patchValue( - config.alarmSource, {emitEvent: false} - ); - const alarmSourceType: DatasourceType = this.alarmSourceSettings.get('type').value; - this.alarmSourceSettings.get('entityAliasId').setValidators( - alarmSourceType === DatasourceType.entity ? [Validators.required] : [] - ); - this.alarmSourceSettings.get('entityAliasId').updateValueAndValidity({emitEvent: false}); } } @@ -553,43 +460,40 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } } - public dataKeysOptional(type?: DatasourceType): boolean { - if (this.widgetType === widgetType.timeseries && this.modelValue?.typeParameters?.hasAdditionalLatestDataKeys) { - return true; + private updateWidgetSettingsEnabledState() { + const showTitle: boolean = this.widgetSettings.get('showTitle').value; + const showTitleIcon: boolean = this.widgetSettings.get('showTitleIcon').value; + if (showTitle) { + this.widgetSettings.get('title').enable({emitEvent: false}); + this.widgetSettings.get('titleTooltip').enable({emitEvent: false}); + this.widgetSettings.get('titleStyle').enable({emitEvent: false}); + this.widgetSettings.get('showTitleIcon').enable({emitEvent: false}); } else { - return this.modelValue.typeParameters && this.modelValue.typeParameters.dataKeysOptional - && type !== DatasourceType.entityCount && type !== DatasourceType.alarmCount; + this.widgetSettings.get('title').disable({emitEvent: false}); + this.widgetSettings.get('titleTooltip').disable({emitEvent: false}); + this.widgetSettings.get('titleStyle').disable({emitEvent: false}); + this.widgetSettings.get('showTitleIcon').disable({emitEvent: false}); + } + if (showTitle && showTitleIcon) { + this.widgetSettings.get('titleIcon').enable({emitEvent: false}); + this.widgetSettings.get('iconColor').enable({emitEvent: false}); + this.widgetSettings.get('iconSize').enable({emitEvent: false}); + } else { + this.widgetSettings.get('titleIcon').disable({emitEvent: false}); + this.widgetSettings.get('iconColor').disable({emitEvent: false}); + this.widgetSettings.get('iconSize').disable({emitEvent: false}); } } - private buildDatasourceForm(datasource?: Datasource): UntypedFormGroup { - const dataKeysRequired = !this.dataKeysOptional(datasource?.type); - const datasourceFormGroup = this.fb.group( - { - type: [datasource ? datasource.type : null, [Validators.required]], - name: [datasource ? datasource.name : null, []], - entityAliasId: [datasource ? datasource.entityAliasId : null, - datasource && (datasource.type === DatasourceType.entity || - datasource.type === DatasourceType.entityCount) ? [Validators.required] : []], - filterId: [datasource ? datasource.filterId : null, []], - dataKeys: [datasource ? datasource.dataKeys : null, dataKeysRequired ? [Validators.required] : []], - alarmFilterConfig: [datasource && datasource.alarmFilterConfig ? - datasource.alarmFilterConfig : { statusList: [AlarmSearchStatus.ACTIVE] }] - } - ); - if (this.widgetType === widgetType.timeseries && this.modelValue?.typeParameters?.hasAdditionalLatestDataKeys) { - datasourceFormGroup.addControl('latestDataKeys', this.fb.control(datasource ? datasource.latestDataKeys : null)); + private updateDataSettingsEnabledState() { + const useDashboardTimewindow: boolean = this.dataSettings.get('useDashboardTimewindow').value; + if (useDashboardTimewindow) { + this.dataSettings.get('displayTimewindow').disable({emitEvent: false}); + this.dataSettings.get('timewindow').disable({emitEvent: false}); + } else { + this.dataSettings.get('displayTimewindow').enable({emitEvent: false}); + this.dataSettings.get('timewindow').enable({emitEvent: false}); } - datasourceFormGroup.get('type').valueChanges.subscribe((type: DatasourceType) => { - datasourceFormGroup.get('entityAliasId').setValidators( - (type === DatasourceType.entity || type === DatasourceType.entityCount) ? [Validators.required] : [] - ); - const newDataKeysRequired = !this.dataKeysOptional(type); - datasourceFormGroup.get('dataKeys').setValidators(newDataKeysRequired ? [Validators.required] : []); - datasourceFormGroup.get('entityAliasId').updateValueAndValidity(); - datasourceFormGroup.get('dataKeys').updateValueAndValidity(); - }); - return datasourceFormGroup; } private updateSchemaForm(settings?: any) { @@ -632,16 +536,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } } - private updateAlarmSourceSettings() { - if (this.modelValue) { - if (this.modelValue.config) { - const alarmSource: Datasource = this.alarmSourceSettings.value; - this.modelValue.config.alarmSource = alarmSource; - } - this.propagateChange(this.modelValue); - } - } - private updateWidgetSettings() { if (this.modelValue) { if (this.modelValue.config) { @@ -663,8 +557,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private updateAdvancedSettings() { if (this.modelValue) { if (this.modelValue.config) { - const settings = this.advancedSettings.get('settings').value?.model; - this.modelValue.config.settings = settings; + this.modelValue.config.settings = this.advancedSettings.get('settings').value?.model; } this.propagateChange(this.modelValue); } @@ -673,19 +566,22 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private updateActionSettings() { if (this.modelValue) { if (this.modelValue.config) { - const actions = (this.actionsSettings.get('actionsData').value as WidgetActionsData).actionsMap; - this.modelValue.config.actions = actions; + this.modelValue.config.actions = (this.actionsSettings.get('actionsData').value as WidgetActionsData).actionsMap; } this.propagateChange(this.modelValue); } } - public displayAdvanced(): boolean { + public get displayAppearance(): boolean { + return this.displayAppearanceDataSettings || this.displayAdvancedAppearance; + } + + public get displayAdvancedAppearance(): boolean { return !!this.modelValue && (!!this.modelValue.settingsSchema && !!this.modelValue.settingsSchema.schema || !!this.modelValue.settingsDirective && !!this.modelValue.settingsDirective.length); } - public displayTimewindowConfig(): boolean { + public get displayTimewindowConfig(): boolean { if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm) { return true; } else if (this.widgetType === widgetType.latest) { @@ -694,40 +590,30 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } } - public onlyHistoryTimewindow(): boolean { - if (this.widgetType === widgetType.latest) { - const datasources = this.dataSettings.get('datasources').value; - return datasourcesHasOnlyComparisonAggregation(datasources); - } else { - return false; - } + public get displayLimits(): boolean { + return this.widgetType !== widgetType.rpc && this.widgetType !== widgetType.alarm && + this.modelValue?.isDataEnabled && !this.modelValue?.typeParameters?.singleEntity; + } + + public get displayAppearanceDataSettings(): boolean { + return this.displayUnitsConfig || this.displayNoDataDisplayMessageConfig; } - public onDatasourceDrop(event: CdkDragDrop) { - const datasourcesFormArray = this.datasourcesFormArray(); - const datasourceForm = datasourcesFormArray.at(event.previousIndex); - datasourcesFormArray.removeAt(event.previousIndex); - datasourcesFormArray.insert(event.currentIndex, datasourceForm); + public get displayUnitsConfig(): boolean { + return this.widgetType === widgetType.latest || this.widgetType === widgetType.timeseries; } - public removeDatasource(index: number) { - this.datasourcesFormArray().removeAt(index); + public get displayNoDataDisplayMessageConfig(): boolean { + return this.widgetType !== widgetType.static && !this.modelValue?.typeParameters?.processNoDataByWidget; } - public addDatasource() { - let newDatasource: Datasource; - if (this.functionsOnly) { - newDatasource = deepClone(this.utils.getDefaultDatasource(this.modelValue.dataKeySettingsSchema.schema)); - newDatasource.dataKeys = [this.generateDataKey('Sin', DataKeyType.function, this.modelValue.dataKeySettingsSchema)]; + public onlyHistoryTimewindow(): boolean { + if (this.widgetType === widgetType.latest) { + const datasources = this.dataSettings.get('datasources').value; + return datasourcesHasOnlyComparisonAggregation(datasources); } else { - newDatasource = { type: DatasourceType.entity, - dataKeys: [] - }; - } - if (this.modelValue?.typeParameters?.hasAdditionalLatestDataKeys) { - newDatasource.latestDataKeys = []; + return false; } - this.datasourcesFormArray().push(this.buildDatasourceForm(newDatasource)); } public generateDataKey(chip: any, type: DataKeyType, datakeySettingsSchema: JsonSettingsSchema): DataKey { @@ -854,8 +740,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } public validate(c: UntypedFormControl) { - this.timeseriesKeyError = false; - this.datasourceError = []; if (!this.dataSettings.valid) { return { dataSettings: { @@ -874,7 +758,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe valid: false } }; - } else if (!this.advancedSettings.valid || (this.displayAdvanced() && !this.modelValue.config.settings)) { + } else if (!this.advancedSettings.valid || (this.displayAdvancedAppearance && !this.modelValue.config.settings)) { return { advancedSettings: { valid: false @@ -890,54 +774,8 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } }; } - } else if (this.widgetType === widgetType.alarm && this.modelValue.isDataEnabled) { - if (!this.alarmSourceSettings.valid || !config.alarmSource) { - return { - alarmSource: { - valid: false - } - }; - } - } else if (this.widgetType !== widgetType.static && this.modelValue.isDataEnabled) { - if (!this.modelValue.typeParameters.datasourcesOptional && (!config.datasources || !config.datasources.length)) { - return { - datasources: { - valid: false - } - }; - } - if (this.widgetType === widgetType.timeseries && this.modelValue?.typeParameters?.hasAdditionalLatestDataKeys) { - let valid = config.datasources.filter(datasource => datasource?.dataKeys?.length).length > 0; - if (!valid) { - this.timeseriesKeyError = true; - return { - timeseriesDataKeys: { - valid: false - } - }; - } else { - const emptyDatasources = config.datasources.filter(datasource => !datasource?.dataKeys?.length && - !datasource?.latestDataKeys?.length); - valid = emptyDatasources.length === 0; - if (!valid) { - for (const emptyDatasource of emptyDatasources) { - const i = config.datasources.indexOf(emptyDatasource); - this.datasourceError[i] = 'At least one data key should be specified'; - } - return { - dataKeys: { - valid: false - } - }; - } - } - } } } return null; } - - public extensionPanelIsOpen(value) { - this.openExtensionPanel = value; - } } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.scss b/ui-ngx/src/app/modules/home/components/widget/widget-config.scss new file mode 100644 index 0000000000..25e91e55be --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.scss @@ -0,0 +1,165 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-widget-config-panel { + box-shadow: 0 0 10px 6px rgba(11, 17, 51, 0.04); + border-radius: 4px; + padding: 16px; + gap: 16px; + display: flex; + flex-direction: column; + color: rgba(0, 0, 0, 0.87); + letter-spacing: 0.15px; + &.no-padding-bottom { + padding-bottom: 0; + } + &.stroked { + box-shadow: none; + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 6px; + } +} +.tb-widget-config-panel-title { + font-weight: 500; + font-size: 16px; +} +.tb-widget-config-panel-hint { + font-size: 12px; + color: #808080; +} +.tb-widget-config-row { + height: 56px; + display: flex; + flex-direction: row; + align-items: center; + gap: 16px; + padding-left: 16px; + padding-right: 12px; + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 6px; + &.same-padding { + padding-right: 16px; + } + &.space-between { + justify-content: space-between; + } + .mat-divider-vertical { + height: 56px; + } +} + +:host ::ng-deep { + + .mat-slide { + margin: 8px 0; + .mdc-form-field>label { + font-weight: 400; + font-size: 16px; + line-height: 24px; + margin-left: 12px; + } + } + + .slide-block { + display: block; + &:not(:last-child) { + margin-bottom: 8px; + } + } + + .tb-widget-config-row { + .mat-mdc-form-field { + .mat-mdc-text-field-wrapper.mdc-text-field--outlined { + padding-right: 12px; + padding-left: 12px; + &:not(.mdc-text-field--focused):not(.mdc-text-field--disabled):not(:hover) { + .mdc-notched-outline__leading, .mdc-notched-outline__trailing { + border-color: rgba(0, 0, 0, 0.12); + } + } + .mat-mdc-form-field-infix { + padding-top: 7px; + padding-bottom: 7px; + min-height: 38px; + width: 72px; + } + } + &.center { + .mat-mdc-text-field-wrapper.mdc-text-field--outlined { + .mat-mdc-form-field-infix { + .mdc-text-field__input { + text-align: center; + } + } + } + } + &.number { + .mat-mdc-text-field-wrapper.mdc-text-field--outlined { + padding-right: 4px; + .mat-mdc-form-field-infix { + width: 80px; + input.mdc-text-field__input[type=number]::-webkit-inner-spin-button, + input.mdc-text-field__input[type=number]::-webkit-outer-spin-button { + opacity: 1; + } + } + } + } + } + } + + .tb-widget-config-panel { + .mat-expansion-panel { + &.tb-settings { + box-shadow: none; + .mat-content { + overflow: visible; + } + .mat-expansion-panel-header { + font-weight: 500; + font-size: 16px; + line-height: 24px; + letter-spacing: 0.25px; + padding: 0; + .mat-content { + flex: 0; + white-space: nowrap; + } + &:hover { + background: none; + } + .mat-expansion-indicator { + height: 32px; + padding: 2px; + } + } + .mat-expansion-panel-header-description { + align-items: center; + } + > .mat-expansion-panel-content { + > .mat-expansion-panel-body { + padding: 0; + } + } + .tb-json-object-panel, .tb-css-content-panel { + margin: 0 0 8px; + } + } + .mat-expansion-panel-content { + font: inherit; + } + } + } +} diff --git a/ui-ngx/src/app/shared/components/color-input.component.html b/ui-ngx/src/app/shared/components/color-input.component.html index 542ec540da..492a2419eb 100644 --- a/ui-ngx/src/app/shared/components/color-input.component.html +++ b/ui-ngx/src/app/shared/components/color-input.component.html @@ -15,7 +15,7 @@ limitations under the License. --> - + {{icon}} {{label}} @@ -34,3 +34,8 @@ {{ requiredText }} + +
+
+
+
diff --git a/ui-ngx/src/app/shared/components/color-input.component.scss b/ui-ngx/src/app/shared/components/color-input.component.scss index 0d5d861272..ca8ffedc72 100644 --- a/ui-ngx/src/app/shared/components/color-input.component.scss +++ b/ui-ngx/src/app/shared/components/color-input.component.scss @@ -25,5 +25,8 @@ .tb-color-preview { margin-left: 8px; margin-right: 5px; + &.no-margin { + margin: 0; + } } } diff --git a/ui-ngx/src/app/shared/components/color-input.component.ts b/ui-ngx/src/app/shared/components/color-input.component.ts index 86199ea627..08432d6967 100644 --- a/ui-ngx/src/app/shared/components/color-input.component.ts +++ b/ui-ngx/src/app/shared/components/color-input.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -22,6 +22,7 @@ import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_AC import { TranslateService } from '@ngx-translate/core'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { DialogService } from '@core/services/dialog.service'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-color-input', @@ -37,6 +38,10 @@ import { DialogService } from '@core/services/dialog.service'; }) export class ColorInputComponent extends PageComponent implements OnInit, ControlValueAccessor { + @Input() + @coerceBoolean() + asBoxInput = false; + @Input() icon: string; @@ -95,7 +100,8 @@ export class ColorInputComponent extends PageComponent implements OnInit, Contro constructor(protected store: Store, private dialogs: DialogService, private translate: TranslateService, - private fb: UntypedFormBuilder) { + private fb: UntypedFormBuilder, + private cd: ChangeDetectorRef) { super(store); } @@ -154,6 +160,7 @@ export class ColorInputComponent extends PageComponent implements OnInit, Contro this.colorFormGroup.patchValue( {color}, {emitEvent: true} ); + this.cd.markForCheck(); } } ); @@ -161,5 +168,6 @@ export class ColorInputComponent extends PageComponent implements OnInit, Contro clear() { this.colorFormGroup.get('color').patchValue(null, {emitEvent: true}); + this.cd.markForCheck(); } } diff --git a/ui-ngx/src/app/shared/components/material-icon-select.component.html b/ui-ngx/src/app/shared/components/material-icon-select.component.html index 925e8beeac..5cf7cb6de7 100644 --- a/ui-ngx/src/app/shared/components/material-icon-select.component.html +++ b/ui-ngx/src/app/shared/components/material-icon-select.component.html @@ -15,8 +15,8 @@ limitations under the License. --> -
- {{materialIconFormGroup.get('icon').value}} +
+ {{materialIconFormGroup.get('icon').value}} {{ label }} @@ -28,3 +28,8 @@
+ + {{materialIconFormGroup.get('icon').value}} + diff --git a/ui-ngx/src/app/shared/components/material-icon-select.component.scss b/ui-ngx/src/app/shared/components/material-icon-select.component.scss index d17df37a47..6bfd308ae5 100644 --- a/ui-ngx/src/app/shared/components/material-icon-select.component.scss +++ b/ui-ngx/src/app/shared/components/material-icon-select.component.scss @@ -14,11 +14,28 @@ * limitations under the License. */ :host { - .mat-icon.icon-value { - padding: 4px; - margin: 12px 4px 4px; - cursor: pointer; - border: solid 1px rgba(0, 0, 0, .27); - box-sizing: initial; + .mat-icon { + &.icon-value { + padding: 4px; + margin: 12px 4px 4px; + cursor: pointer; + border: solid 1px rgba(0, 0, 0, .27); + box-sizing: initial; + } + &.icon-box { + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 4px; + cursor: pointer; + box-sizing: border-box; + padding: 8px; + height: 40px; + width: 40px; + font-size: 22px; + vertical-align: middle; + &.disabled { + cursor: initial; + color: rgba(0, 0, 0, 0.38); + } + } } } diff --git a/ui-ngx/src/app/shared/components/material-icon-select.component.ts b/ui-ngx/src/app/shared/components/material-icon-select.component.ts index 715c9161a3..b8bb7ed25b 100644 --- a/ui-ngx/src/app/shared/components/material-icon-select.component.ts +++ b/ui-ngx/src/app/shared/components/material-icon-select.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -22,6 +22,7 @@ import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_AC import { DialogService } from '@core/services/dialog.service'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { TranslateService } from '@ngx-translate/core'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-material-icon-select', @@ -37,9 +38,16 @@ import { TranslateService } from '@ngx-translate/core'; }) export class MaterialIconSelectComponent extends PageComponent implements OnInit, ControlValueAccessor { + @Input() + @coerceBoolean() + asBoxInput = false; + @Input() label = this.translate.instant('icon.icon'); + @Input() + color: string; + @Input() disabled: boolean; @@ -73,7 +81,8 @@ export class MaterialIconSelectComponent extends PageComponent implements OnInit constructor(protected store: Store, private dialogs: DialogService, private translate: TranslateService, - private fb: UntypedFormBuilder) { + private fb: UntypedFormBuilder, + private cd: ChangeDetectorRef) { super(store); } @@ -126,6 +135,7 @@ export class MaterialIconSelectComponent extends PageComponent implements OnInit this.materialIconFormGroup.patchValue( {icon}, {emitEvent: true} ); + this.cd.markForCheck(); } } ); @@ -134,5 +144,6 @@ export class MaterialIconSelectComponent extends PageComponent implements OnInit clear() { this.materialIconFormGroup.get('icon').patchValue(null, {emitEvent: true}); + this.cd.markForCheck(); } } diff --git a/ui-ngx/src/app/shared/components/toggle-header.component.scss b/ui-ngx/src/app/shared/components/toggle-header.component.scss index 683d364058..e135030bed 100644 --- a/ui-ngx/src/app/shared/components/toggle-header.component.scss +++ b/ui-ngx/src/app/shared/components/toggle-header.component.scss @@ -14,6 +14,7 @@ * limitations under the License. */ +@import "../../../theme"; @import "../../../scss/constants"; :host ::ng-deep { @@ -47,8 +48,8 @@ &.mat-button-toggle-checked { .mat-button-toggle-button { background: #F3F6FA; - color: #305680; - border: 1px solid #305680; + color: $tb-primary-color; + border: 1px solid $tb-primary-color; border-radius: 20px; .mat-button-toggle-label-content { @@ -62,7 +63,7 @@ .mat-button-toggle.mat-button-toggle-appearance-standard { &.mat-button-toggle-checked { .mat-button-toggle-button { - background: #305680; + background: $tb-primary-color; color: #FFFFFF; } } 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 432c03f4b3..cde95a9f45 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1114,6 +1114,10 @@ "function-types": "Function types", "function-type": "Function type", "function-types-required": "Function types are required.", + "data-keys": "Data keys", + "data-key": "Data key", + "data-keys-required": "Data keys are required.", + "data-key-required": "Data key is required.", "alarm-keys": "Alarm data keys", "alarm-key": "Alarm data key", "alarm-key-functions": "Alarm key functions", @@ -1972,6 +1976,7 @@ "no-aliases-found": "No aliases found.", "no-alias-matching": "'{{alias}}' not found.", "create-new-alias": "Create a new one!", + "create-new": "Create new", "key": "Key", "key-name": "Key name", "no-keys-found": "No keys found.", @@ -2426,6 +2431,7 @@ "add-filter-prompt": "Please add filter", "no-filter-matching": "'{{filter}}' not found.", "create-new-filter": "Create a new one!", + "create-new": "Create new", "filter-required": "Filter is required.", "operation": { "operation": "Operation", @@ -4117,10 +4123,12 @@ "decimals": "Number of digits after floating point", "timewindow": "Timewindow", "use-dashboard-timewindow": "Use dashboard timewindow", + "use-widget-timewindow": "Use widget timewindow", "display-timewindow": "Display timewindow", "legend": "Legend", "display-legend": "Display legend", "datasources": "Datasources", + "datasource": "Datasource", "maximum-datasources": "Maximum { count, plural, =1 {1 datasource is allowed.} other {# datasources are allowed} }", "timeseries-key-error": "At least one timeseries data key should be specified", "datasource-type": "Type", @@ -4153,10 +4161,20 @@ "icon-size": "Icon size", "advanced-settings": "Advanced settings", "data-settings": "Data settings", + "limits": "Limits", "no-data-display-message": "\"No data to display\" alternative message", "data-page-size": "Maximum entities per datasource", "settings-component-not-found": "Settings form component not found for selector '{{selector}}'", - "preview": "Preview" + "preview": "Preview", + "set": "Set", + "set-message": "Set message", + "card-title": "Card title", + "advanced-title-style": "Advanced title style", + "card-style": "Card style", + "text": "Text", + "background": "Background", + "advanced-widget-style": "Advanced widget style", + "card-buttons": "Card buttons" }, "widget-type": { "import": "Import widget type", diff --git a/ui-ngx/src/styles.scss b/ui-ngx/src/styles.scss index 39885d1191..407ba6c1eb 100644 --- a/ui-ngx/src/styles.scss +++ b/ui-ngx/src/styles.scss @@ -1083,6 +1083,27 @@ mat-label { border-radius: 50%; box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .14), 0 2px 2px 0 rgba(0, 0, 0, .098), 0 1px 5px 0 rgba(0, 0, 0, .084); + &.box { + border: none; + box-shadow: none; + border-radius: 4px; + .tb-color-result { + border: 1px solid rgba(0, 0, 0, 0.12); + } + &.disabled { + cursor: initial; + .tb-color-result { + background: rgba(0, 0, 0, 0.38); + } + } + } + + &.small { + width: 18px; + min-width: 18px; + height: 18px; + } + @include tb-checkered-bg(); .tb-color-result { From e8c57c9d5a60e48ed107449497b3e820918dbca5 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Fri, 19 May 2023 18:01:37 +0300 Subject: [PATCH 074/207] UI: Added allow edit notification template in template selector --- .../rule-notification-dialog.component.html | 3 +- .../sent-notification-dialog.component.html | 3 +- .../template-autocomplete.component.html | 8 ++++++ .../template-autocomplete.component.ts | 28 ++++++++++++++++--- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html index fc48392e8c..4e7a133009 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html @@ -59,8 +59,7 @@ diff --git a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html index 27b8968344..4ff13778e5 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html @@ -49,8 +49,7 @@
diff --git a/ui-ngx/src/app/shared/components/notification/template-autocomplete.component.html b/ui-ngx/src/app/shared/components/notification/template-autocomplete.component.html index 8657228de6..3fe45a4da0 100644 --- a/ui-ngx/src/app/shared/components/notification/template-autocomplete.component.html +++ b/ui-ngx/src/app/shared/components/notification/template-autocomplete.component.html @@ -29,6 +29,14 @@ (click)="clear()"> close + - + + + +
- + + - -
@@ -164,6 +157,14 @@ + +
@@ -62,13 +85,6 @@ cdkFocusInitial> {{ 'widget-config.preview' | translate }} - +
-
- -
- -
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.scss b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.scss new file mode 100644 index 0000000000..9777decdb0 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.scss @@ -0,0 +1,26 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host { + .widget-preview-section { + position: absolute; + top: 72px; + left: 16px; + right: 16px; + bottom: 16px; + border: 1px solid rgba(0, 0, 0, 0.05); + border-radius: 4px; + } +} diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts index 756709966f..f910f79b01 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.ts @@ -14,32 +14,23 @@ /// limitations under the License. /// -import { - ChangeDetectionStrategy, - Component, - EventEmitter, - Input, - OnChanges, - OnInit, - Output, - SimpleChanges -} from '@angular/core'; +import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { MatDialog } from '@angular/material/dialog'; import { Dashboard, WidgetLayout } from '@shared/models/dashboard.models'; import { IAliasController, IStateController } from '@core/api/widget-api.models'; -import { Widget } from '@shared/models/widget.models'; +import { Widget, WidgetConfigMode } from '@shared/models/widget.models'; import { WidgetComponentService } from '@home/components/widget/widget-component.service'; import { WidgetConfigComponentData } from '../../models/widget-component.models'; -import { isDefined, isString } from '@core/utils'; +import { isDefined, isDefinedAndNotNull, isString } from '@core/utils'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; @Component({ selector: 'tb-edit-widget', templateUrl: './edit-widget.component.html', - styleUrls: [] + styleUrls: ['./edit-widget.component.scss'] }) export class EditWidgetComponent extends PageComponent implements OnInit, OnChanges { @@ -73,6 +64,21 @@ export class EditWidgetComponent extends PageComponent implements OnInit, OnChan previewMode = false; + hasBasicMode = false; + + get widgetConfigMode(): WidgetConfigMode { + return this.hasBasicMode ? (this.widgetConfig?.config?.configMode || WidgetConfigMode.advanced) : WidgetConfigMode.advanced; + } + + set widgetConfigMode(widgetConfigMode: WidgetConfigMode) { + if (this.hasBasicMode) { + this.widgetConfig.config.configMode = widgetConfigMode; + this.widgetFormGroup.markAsDirty(); + } + } + + private currentWidgetConfigChanged = false; + constructor(protected store: Store, private dialog: MatDialog, private fb: UntypedFormBuilder, @@ -98,18 +104,24 @@ export class EditWidgetComponent extends PageComponent implements OnInit, OnChan } } if (reloadConfig) { - this.previewMode = false; + if (this.currentWidgetConfigChanged) { + this.currentWidgetConfigChanged = false; + } else { + this.previewMode = false; + } this.loadWidgetConfig(); } } onApplyWidgetConfig() { if (this.widgetFormGroup.valid) { + this.currentWidgetConfigChanged = true; this.applyWidgetConfig.emit(); } } onRevertWidgetConfig() { + this.currentWidgetConfigChanged = true; this.revertWidgetConfig.emit(); } @@ -144,6 +156,7 @@ export class EditWidgetComponent extends PageComponent implements OnInit, OnChan JSON.parse(rawLatestDataKeySettingsSchema) : rawLatestDataKeySettingsSchema; } this.widgetConfig = { + widgetName: widgetInfo.widgetName, config: this.widget.config, layout: this.widgetLayout, widgetType: this.widget.type, @@ -155,8 +168,9 @@ export class EditWidgetComponent extends PageComponent implements OnInit, OnChan latestDataKeySettingsSchema, settingsDirective: widgetInfo.settingsDirective, dataKeySettingsDirective: widgetInfo.dataKeySettingsDirective, - latestDataKeySettingsDirective: widgetInfo.latestDataKeySettingsDirective + latestDataKeySettingsDirective: widgetInfo.latestDataKeySettingsDirective, }; + this.hasBasicMode = isDefinedAndNotNull(widgetInfo.hasBasicMode) ? widgetInfo.hasBasicMode : false; this.widgetFormGroup.reset({widgetConfig: this.widgetConfig}); } } diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index 5789c6ff5c..a8ad2fd4c4 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -183,6 +183,9 @@ import { DeviceInfoFilterComponent } from '@home/components/device/device-info-f import { WidgetPreviewComponent } from '@home/components/widget/widget-preview.component'; import { DatasourceComponent } from '@home/components/widget/datasource.component'; import { DatasourcesComponent } from '@home/components/widget/datasources.component'; +import { + ManageWidgetActionsDialogComponent +} from '@home/components/widget/action/manage-widget-actions-dialog.component'; @NgModule({ declarations: @@ -234,6 +237,7 @@ import { DatasourcesComponent } from '@home/components/widget/datasources.compon DataKeyConfigDialogComponent, ManageWidgetActionsComponent, WidgetActionDialogComponent, + ManageWidgetActionsDialogComponent, CustomActionPrettyResourcesTabsComponent, CustomActionPrettyEditorComponent, MobileActionEditorComponent, @@ -386,6 +390,7 @@ import { DatasourcesComponent } from '@home/components/widget/datasources.compon DataKeyConfigDialogComponent, ManageWidgetActionsComponent, WidgetActionDialogComponent, + ManageWidgetActionsDialogComponent, CustomActionPrettyResourcesTabsComponent, CustomActionPrettyEditorComponent, MobileActionEditorComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions-dialog.component.html new file mode 100644 index 0000000000..37db477dd0 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions-dialog.component.html @@ -0,0 +1,51 @@ + +
+ +

{{ data.widgetTitle }}: {{ 'widget-config.actions' | translate }}

+ + +
+ + +
+
+ + +
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions-dialog.component.ts new file mode 100644 index 0000000000..f458243c10 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions-dialog.component.ts @@ -0,0 +1,70 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { widgetType } from '@shared/models/widget.models'; +import { + WidgetActionCallbacks, + WidgetActionsData +} from '@home/components/widget/action/manage-widget-actions.component.models'; +import { Component, Inject, OnInit } from '@angular/core'; +import { DialogComponent } from '@shared/components/dialog.component'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { Router } from '@angular/router'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; + +export interface ManageWidgetActionsDialogData { + widgetTitle: string; + actionsData: WidgetActionsData; + callbacks: WidgetActionCallbacks; + widgetType: widgetType; +} + +@Component({ + selector: 'tb-manage-widget-actions-dialog', + templateUrl: './manage-widget-actions-dialog.component.html', + providers: [], + styleUrls: [] +}) +export class ManageWidgetActionsDialogComponent extends DialogComponent implements OnInit { + + actionsSettings: UntypedFormGroup; + + constructor(protected store: Store, + protected router: Router, + @Inject(MAT_DIALOG_DATA) public data: ManageWidgetActionsDialogData, + private fb: UntypedFormBuilder, + public dialogRef: MatDialogRef) { + super(store, router, dialogRef); + } + + ngOnInit() { + this.actionsSettings = this.fb.group({ + actionsData: [this.data.actionsData, []] + }); + } + + cancel(): void { + this.dialogRef.close(null); + } + + save(): void { + this.dialogRef.close(this.actionsSettings.get('actionsData').value); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html index 7a85c37973..46475911fb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.html @@ -15,8 +15,8 @@ limitations under the License. --> -
-
+
+
widget-config.actions diff --git a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.scss b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.scss index a42feda512..2e2e1687fc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.scss @@ -24,12 +24,6 @@ background: #fff; overflow: hidden; - &.tb-outlined-border { - box-shadow: 0 0 0 0 rgb(0 0 0 / 20%), 0 0 0 0 rgb(0 0 0 / 14%), 0 0 0 0 rgb(0 0 0 / 12%); - border: solid 1px #e0e0e0; - border-radius: 4px; - } - .tb-entity-table-title { padding-right: 20px; white-space: nowrap; diff --git a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts index d18c1319f4..925435885f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.ts @@ -89,6 +89,7 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni dragDisabled = true; private widgetResize$: ResizeObserver; + private destroyed = false; @ViewChild('searchInput') searchInputField: ElementRef; @@ -123,6 +124,7 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni } ngOnDestroy(): void { + this.destroyed = true; if (this.widgetResize$) { this.widgetResize$.disconnect(); } @@ -340,11 +342,13 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni this.innerValue = obj; if (this.innerValue) { setTimeout(() => { - this.dataSource.setActions(this.innerValue); - if (this.viewsInited) { - this.resetSortAndFilter(true); - } else { - this.dirtyValue = true; + if (!this.destroyed) { + this.dataSource.setActions(this.innerValue); + if (this.viewsInited) { + this.resetSortAndFilter(true); + } else { + this.dirtyValue = true; + } } }, 0); } diff --git a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html index 01b928e354..6cd6679934 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html @@ -32,6 +32,7 @@
- + notifications @@ -112,7 +112,7 @@ [displayWith]="displayKeyFn"> - + notifications @@ -139,7 +139,7 @@ {{ translate.get('entity.no-key-matching', {key: truncate.transform(searchText, true, 6, '...')}) | async }} - + entity.create-new-key diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.models.ts index 9407145376..a5519be953 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.models.ts @@ -21,4 +21,5 @@ import { Observable } from 'rxjs'; export interface DataKeysCallbacks { generateDataKey: (chip: any, type: DataKeyType, datakeySettingsSchema: JsonSettingsSchema) => DataKey; fetchEntityKeys: (entityAliasId: string, types: Array) => Observable>; + fetchEntityKeysForDevice: (deviceId: string, types: Array) => Observable>; } diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts index 71b4121c9b..5e4dafe6cf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts @@ -37,8 +37,8 @@ import { NgForm, UntypedFormBuilder, UntypedFormControl, - UntypedFormGroup, ValidationErrors, - Validators + UntypedFormGroup, + ValidationErrors } from '@angular/forms'; import { Observable, of } from 'rxjs'; import { filter, map, mergeMap, publishReplay, refCount, share, tap } from 'rxjs/operators'; @@ -140,6 +140,9 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange @Input() entityAliasId: string; + @Input() + deviceId: string; + private requiredValue: boolean; get required(): boolean { return this.requiredValue || !this.optDataKeys || this.isCountDatasource; @@ -326,15 +329,21 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange for (const propName of Object.keys(changes)) { const change = changes[propName]; if (!change.firstChange && change.currentValue !== change.previousValue) { - if (propName === 'entityAliasId') { + if (['deviceId', 'entityAliasId'].includes(propName)) { this.clearSearchCache(); this.dirty = true; } else if (['widgetType', 'datasourceType', 'maxDataKeys', 'simpleDataKeysLabel'].includes(propName)) { - this.clearSearchCache(); - this.updateParams(); - setTimeout(() => { - this.reset(); - }, 1); + if (propName === 'datasourceType' && + [DatasourceType.device, DatasourceType.entity].includes(change.previousValue) && + [DatasourceType.device, DatasourceType.entity].includes(change.currentValue)) { + this.clearSearchCache(); + } else { + this.clearSearchCache(); + this.updateParams(); + setTimeout(() => { + this.reset(); + }, 1); + } } else if (['required', 'optDataKeys'].includes(propName)) { this.updateValidators(); } @@ -468,6 +477,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange aliasController: this.aliasController, widget: this.widget, widgetType: this.widgetType, + deviceId: this.deviceId, entityAliasId: this.entityAliasId, showPostProcessing: this.widgetType !== widgetType.alarm, callbacks: this.callbacks @@ -517,7 +527,8 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange if (this.datasourceType === DatasourceType.function) { const targetKeysList = this.widgetType === widgetType.alarm ? this.alarmKeys : this.functionTypeKeys; fetchObservable = of(targetKeysList); - } else if (this.datasourceType === DatasourceType.entity && this.entityAliasId) { + } else if (this.datasourceType === DatasourceType.entity && this.entityAliasId || + this.datasourceType === DatasourceType.device && this.deviceId) { const dataKeyTypes = [DataKeyType.timeseries]; if (this.widgetType === widgetType.latest || this.widgetType === widgetType.alarm) { dataKeyTypes.push(DataKeyType.attribute); @@ -526,7 +537,11 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange dataKeyTypes.push(DataKeyType.alarm); } } - fetchObservable = this.callbacks.fetchEntityKeys(this.entityAliasId, dataKeyTypes); + if (this.datasourceType === DatasourceType.device) { + fetchObservable = this.callbacks.fetchEntityKeysForDevice(this.deviceId, dataKeyTypes); + } else { + fetchObservable = this.callbacks.fetchEntityKeys(this.entityAliasId, dataKeyTypes); + } } else { fetchObservable = of([]); } @@ -563,6 +578,10 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange return [DatasourceType.entityCount, DatasourceType.alarmCount].includes(this.datasourceType); } + get isEntityDatasource(): boolean { + return [DatasourceType.device, DatasourceType.entity].includes(this.datasourceType); + } + get inputDisabled(): boolean { return this.isCountDatasource || (this.maxDataKeysSet && this.keys.length >= this.maxDataKeys); } diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.html b/ui-ngx/src/app/modules/home/components/widget/datasource.component.html index 797415e687..40c63e6764 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasource.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/datasource.component.html @@ -32,15 +32,21 @@ formControlName="name"> - + + + diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts b/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts index 1d6053e024..3f521b1d91 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts @@ -40,6 +40,7 @@ import { IAliasController } from '@core/api/widget-api.models'; import { EntityAliasSelectCallbacks } from '@home/components/alias/entity-alias-select.component.models'; import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models'; import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; +import { EntityType } from '@shared/models/entity-type.models'; @Component({ selector: 'tb-datasource', @@ -122,6 +123,8 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida widgetTypes = widgetType; + entityType = EntityType; + datasourceType = DatasourceType; datasourceTypes: Array = []; datasourceTypesTranslations = datasourceTypeTranslationMap; @@ -160,7 +163,7 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida if (this.widgetConfigComponent.functionsOnly) { this.datasourceTypes = [DatasourceType.function]; } else { - this.datasourceTypes = [DatasourceType.function, DatasourceType.entity]; + this.datasourceTypes = [DatasourceType.function, DatasourceType.device, DatasourceType.entity]; if (this.widgetConfigComponent.widgetType === widgetType.latest) { this.datasourceTypes.push(DatasourceType.entityCount); this.datasourceTypes.push(DatasourceType.alarmCount); @@ -171,6 +174,7 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida { type: [null, [Validators.required]], name: [null, []], + deviceId: [null, []], entityAliasId: [null, []], filterId: [null, []], dataKeys: [null, []], @@ -194,6 +198,7 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida this.datasourceFormGroup.patchValue({ type: datasource?.type, name: datasource?.name, + deviceId: datasource?.deviceId, entityAliasId: datasource?.entityAliasId, filterId: datasource?.filterId, dataKeys: datasource?.dataKeys, @@ -231,11 +236,15 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida private updateValidators() { const type: DatasourceType = this.datasourceFormGroup.get('type').value; + this.datasourceFormGroup.get('deviceId').setValidators( + type === DatasourceType.device ? [Validators.required] : [] + ); this.datasourceFormGroup.get('entityAliasId').setValidators( (type === DatasourceType.entity || type === DatasourceType.entityCount) ? [Validators.required] : [] ); const newDataKeysRequired = !this.isDataKeysOptional(type); this.datasourceFormGroup.get('dataKeys').setValidators(newDataKeysRequired ? [Validators.required] : []); + this.datasourceFormGroup.get('deviceId').updateValueAndValidity({emitEvent: false}); this.datasourceFormGroup.get('entityAliasId').updateValueAndValidity({emitEvent: false}); this.datasourceFormGroup.get('dataKeys').updateValueAndValidity({emitEvent: false}); } diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.html b/ui-ngx/src/app/modules/home/components/widget/datasources.component.html index ef109765b0..98bbe96600 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasources.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/datasources.component.html @@ -77,7 +77,7 @@
-
+
+ +
+
+
+
+ + +
+
+
timewindow.timewindow
+ + +
+
+ + + {{ 'widget-config.display-timewindow' | translate }} + +
+
+
+ +
+
+ + +
+
+
widget-config.target-device
+
+ + +
+
+
+
widget-config.alarm-source
+ + +
+
+
widget-config.limits
+
+
widget-config.data-page-size
+ + + +
+
+
+ +
+
widget-config.data-settings
+
+
widget-config.units
+ + + +
+
+
widget-config.decimals
+ + + +
+
+
widget-config.no-data-display-message
+ + + +
+
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index cf01244a0c..8eafe8855e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -26,6 +26,8 @@ import { JsonSchema, JsonSettingsSchema, Widget, + WidgetActionDescriptor, + WidgetConfigMode, widgetType } from '@shared/models/widget.models'; import { @@ -60,9 +62,14 @@ import { JsonFormComponentData } from '@shared/components/json-form/json-form-co import { WidgetActionsData } from './action/manage-widget-actions.component.models'; import { Dashboard } from '@shared/models/dashboard.models'; import { entityFields } from '@shared/models/entity.models'; -import { Filter } from '@shared/models/query/query.models'; +import { Filter, singleEntityFilterFromDeviceId } from '@shared/models/query/query.models'; import { FilterDialogComponent, FilterDialogData } from '@home/components/filter/filter-dialog.component'; import { ToggleHeaderOption } from '@shared/components/toggle-header.component'; +import { coerceBoolean } from '@shared/decorators/coercion'; +import { + ManageWidgetActionsDialogComponent, + ManageWidgetActionsDialogData +} from '@home/components/widget/action/manage-widget-actions-dialog.component'; const emptySettingsSchema: JsonSchema = { type: 'object', @@ -94,6 +101,8 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe widgetTypes = widgetType; + widgetConfigModes = WidgetConfigMode; + entityTypes = EntityType; @Input() @@ -111,14 +120,26 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe @Input() functionsOnly: boolean; + @Input() + @coerceBoolean() + hideHeader = false; + + @Input() + @coerceBoolean() + hideToggleHeader = false; + @Input() disabled: boolean; + @Input() + widgetConfigMode = WidgetConfigMode.advanced; + widgetType: widgetType; widgetConfigCallbacks: WidgetConfigCallbacks = { createEntityAlias: this.createEntityAlias.bind(this), createFilter: this.createFilter.bind(this), generateDataKey: this.generateDataKey.bind(this), + fetchEntityKeysForDevice: this.fetchEntityKeysForDevice.bind(this), fetchEntityKeys: this.fetchEntityKeys.bind(this), fetchDashboardStates: this.fetchDashboardStates.bind(this) }; @@ -151,7 +172,8 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private entityService: EntityService, private dialog: MatDialog, public translate: TranslateService, - private fb: UntypedFormBuilder) { + private fb: UntypedFormBuilder, + private cd: ChangeDetectorRef) { super(store); } @@ -288,7 +310,9 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe value: 'mobile' } ); - this.selectedOption = this.headerOptions[0].value; + if (!this.selectedOption || !this.headerOptions.find(o => o.value === this.selectedOption)) { + this.selectedOption = this.headerOptions[0].value; + } } private buildForms() { @@ -607,6 +631,28 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe return this.widgetType !== widgetType.static && !this.modelValue?.typeParameters?.processNoDataByWidget; } + public get widgetActionSourceIds(): Array { + const actionsData: WidgetActionsData = this.actionsSettings.get('actionsData').value; + return actionsData?.actionsMap ? Object.keys(actionsData.actionsMap) : []; + } + + public widgetActionsByActionSourceId(actionSourceId: string): Array { + const actionsData: WidgetActionsData = this.actionsSettings.get('actionsData').value; + return actionsData?.actionsMap[actionSourceId] || []; + } + + public get hasWidgetActions(): boolean { + const actionsData: WidgetActionsData = this.actionsSettings.get('actionsData').value; + if (actionsData?.actionsMap) { + for (const actionSourceId of Object.keys(actionsData.actionsMap)) { + if (actionsData.actionsMap[actionSourceId] && actionsData.actionsMap[actionSourceId].length) { + return true; + } + } + } + return false; + } + public onlyHistoryTimewindow(): boolean { if (this.widgetType === widgetType.latest) { const datasources = this.dataSettings.get('datasources').value; @@ -616,6 +662,28 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } } + public manageWidgetActions() { + const actionsData: WidgetActionsData = this.actionsSettings.get('actionsData').value; + this.dialog.open(ManageWidgetActionsDialogComponent, { + disableClose: true, + panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], + data: { + widgetTitle: this.modelValue.widgetName, + callbacks: this.widgetConfigCallbacks, + actionsData: deepClone(actionsData), + widgetType: this.widgetType + } + }).afterClosed().subscribe( + (res) => { + if (res) { + this.actionsSettings.get('actionsData').patchValue(res); + this.cd.markForCheck(); + } + } + ); + } + public generateDataKey(chip: any, type: DataKeyType, datakeySettingsSchema: JsonSettingsSchema): DataKey { if (isObject(chip)) { (chip as DataKey)._hash = Math.random(); @@ -711,6 +779,17 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe ); } + private fetchEntityKeysForDevice(deviceId: string, dataKeyTypes: Array): Observable> { + const entityFilter = singleEntityFilterFromDeviceId(deviceId); + return this.entityService.getEntityKeysByEntityFilter( + entityFilter, + dataKeyTypes, + {ignoreLoading: true, ignoreErrors: true} + ).pipe( + catchError(() => of([])) + ); + } + private fetchEntityKeys(entityAliasId: string, dataKeyTypes: Array): Observable> { return this.aliasController.getAliasInfo(entityAliasId).pipe( mergeMap((aliasInfo) => this.entityService.getEntityKeysByEntityFilter( diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.scss b/ui-ngx/src/app/modules/home/components/widget/widget-config.scss index 25e91e55be..bc269e5a67 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.scss +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.scss @@ -22,6 +22,7 @@ flex-direction: column; color: rgba(0, 0, 0, 0.87); letter-spacing: 0.15px; + position: relative; &.no-padding-bottom { padding-bottom: 0; } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html index 7948cb19d4..7d64036838 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html @@ -26,7 +26,6 @@ [isEditActionEnabled]="false" [isRemoveActionEnabled]="false"> -widget-config.preview
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.scss b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.scss index 73636f346b..1782251f61 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.scss @@ -23,20 +23,10 @@ left: 0; right: 0; } - .tb-preview-title { - position: absolute; - top: 16px; - left: 16px; - font-weight: 500; - font-size: 13px; - line-height: 16px; - letter-spacing: normal; - color: rgba(0, 0, 0, 0.38); - } .tb-preview-panel { position: absolute; top: 16px; - right: 24px; + left: 24px; } } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts index 3d82caa9a7..4b62bba653 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts @@ -14,8 +14,7 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; -import { ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, Validator } from '@angular/forms'; +import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { IAliasController, IStateController } from '@core/api/widget-api.models'; import { Widget, WidgetConfig } from '@shared/models/widget.models'; @@ -28,7 +27,7 @@ import { deepClone } from '@core/utils'; templateUrl: './widget-preview.component.html', styleUrls: ['./widget-preview.component.scss'] }) -export class WidgetPreviewComponent extends PageComponent implements OnInit { +export class WidgetPreviewComponent extends PageComponent implements OnInit, OnChanges { @Input() aliasController: IAliasController; @@ -49,6 +48,25 @@ export class WidgetPreviewComponent extends PageComponent implements OnInit { } ngOnInit(): void { + this.loadPreviewWidget(); + } + + ngOnChanges(changes: SimpleChanges): void { + let reloadPreviewWidget = false; + for (const propName of Object.keys(changes)) { + const change = changes[propName]; + if (!change.firstChange && change.currentValue !== change.previousValue) { + if (['widget', 'widgetConfig'].includes(propName)) { + reloadPreviewWidget = true; + } + } + } + if (reloadPreviewWidget) { + this.loadPreviewWidget(); + } + } + + private loadPreviewWidget() { const sizeX = this.widget.sizeX * 2; const sizeY = this.widget.sizeY * 2; const col = Math.floor(Math.max(0, (20 - sizeX) / 2)); diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index 8ddb3d6218..090d637c99 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -447,6 +447,7 @@ export interface WidgetInfo extends WidgetTypeDescriptor, WidgetControllerDescri } export interface WidgetConfigComponentData { + widgetName: string; config: WidgetConfig; layout: WidgetLayout; widgetType: widgetType; @@ -551,6 +552,8 @@ export function toWidgetInfo(widgetTypeEntity: WidgetType): WidgetInfo { settingsDirective: widgetTypeEntity.descriptor.settingsDirective, dataKeySettingsDirective: widgetTypeEntity.descriptor.dataKeySettingsDirective, latestDataKeySettingsDirective: widgetTypeEntity.descriptor.latestDataKeySettingsDirective, + hasBasicMode: widgetTypeEntity.descriptor.hasBasicMode, + basicModeDirective: widgetTypeEntity.descriptor.basicModeDirective, defaultConfig: widgetTypeEntity.descriptor.defaultConfig }; } @@ -581,6 +584,8 @@ export function toWidgetType(widgetInfo: WidgetInfo, id: WidgetTypeId, tenantId: settingsDirective: widgetInfo.settingsDirective, dataKeySettingsDirective: widgetInfo.dataKeySettingsDirective, latestDataKeySettingsDirective: widgetInfo.latestDataKeySettingsDirective, + hasBasicMode: widgetInfo.hasBasicMode, + basicModeDirective: widgetInfo.basicModeDirective, defaultConfig: widgetInfo.defaultConfig }; return { diff --git a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html index c4b859038e..046ad5acb2 100644 --- a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html +++ b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html @@ -270,6 +270,17 @@ [(ngModel)]="widget.latestDataKeySettingsDirective" (ngModelChange)="isDirty = true"/> + + {{ 'widget.has-basic-mode' | translate }} + + + widget.basic-mode-form-selector + +
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 a8cd40f9b8..af0373b7a9 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 @@ -38,7 +38,7 @@ import { EntityId } from '@shared/models/id/entity-id'; import { EntityService } from '@core/http/entity.service'; import { getCurrentAuthUser } from '@core/auth/auth.selectors'; import { Authority } from '@shared/models/authority.enum'; -import { isEqual } from '@core/utils'; +import { isDefinedAndNotNull, isEqual } from '@core/utils'; import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ @@ -291,7 +291,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit async writeValue(value: string | EntityId | null): Promise { this.searchText = ''; - if (value !== null && (typeof value === 'string' || (value.entityType && value.id))) { + if (isDefinedAndNotNull(value) && (typeof value === 'string' || (value.entityType && value.id))) { let targetEntityType: EntityType; let id: string; if (typeof value === 'string') { diff --git a/ui-ngx/src/app/shared/components/toggle-header.component.html b/ui-ngx/src/app/shared/components/toggle-header.component.html index 3cc0f8beaf..e36cdbd592 100644 --- a/ui-ngx/src/app/shared/components/toggle-header.component.html +++ b/ui-ngx/src/app/shared/components/toggle-header.component.html @@ -16,9 +16,11 @@ --> - {{ option.name }} + {{ option.name }} diff --git a/ui-ngx/src/app/shared/components/toggle-header.component.scss b/ui-ngx/src/app/shared/components/toggle-header.component.scss index e135030bed..a9542012d4 100644 --- a/ui-ngx/src/app/shared/components/toggle-header.component.scss +++ b/ui-ngx/src/app/shared/components/toggle-header.component.scss @@ -68,6 +68,17 @@ } } } + &.tb-invert { + .mat-button-toggle.mat-button-toggle-appearance-standard { + color: rgba(255, 255, 255, 0.8); + &.mat-button-toggle-checked { + .mat-button-toggle-button { + background: #FFFFFF; + color: $tb-primary-color; + } + } + } + } } } @media #{$mat-md-lg} { diff --git a/ui-ngx/src/app/shared/components/toggle-header.component.ts b/ui-ngx/src/app/shared/components/toggle-header.component.ts index 7a66ac6c16..a7f37f53a4 100644 --- a/ui-ngx/src/app/shared/components/toggle-header.component.ts +++ b/ui-ngx/src/app/shared/components/toggle-header.component.ts @@ -38,13 +38,14 @@ import { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button- import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout'; import { MediaBreakpoints } from '@shared/models/constants'; import { coerceBoolean } from '@shared/decorators/coercion'; +import { BreadCrumb } from '@shared/components/breadcrumb'; export interface ToggleHeaderOption { name: string; value: any; } -export type ToggleHeaderAppearance = 'fill' | 'stroked'; +export type ToggleHeaderAppearance = 'fill' | 'fill-invert' | 'stroked'; @Component({ selector: 'tb-toggle-header', @@ -96,4 +97,8 @@ export class ToggleHeaderComponent extends PageComponent implements OnInit { } ); } + + trackByHeaderOption(index: number, option: ToggleHeaderOption){ + return option.value; + } } diff --git a/ui-ngx/src/app/shared/models/query/query.models.ts b/ui-ngx/src/app/shared/models/query/query.models.ts index 4ee89fc89f..7c978fb4c9 100644 --- a/ui-ngx/src/app/shared/models/query/query.models.ts +++ b/ui-ngx/src/app/shared/models/query/query.models.ts @@ -749,6 +749,14 @@ export function createDefaultEntityDataPageLink(pageSize: number): EntityDataPag export const singleEntityDataPageLink: EntityDataPageLink = createDefaultEntityDataPageLink(1); +export const singleEntityFilterFromDeviceId = (deviceId: string): EntityFilter => ({ + type: AliasFilterType.singleEntity, + singleEntity: { + entityType: EntityType.DEVICE, + id: deviceId + } +}); + export interface EntityCountQuery { entityFilter: EntityFilter; keyFilters?: Array; diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index 77d2acf3e2..bfe9021926 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -162,6 +162,8 @@ export interface WidgetTypeDescriptor { settingsDirective?: string; dataKeySettingsDirective?: string; latestDataKeySettingsDirective?: string; + hasBasicMode?: boolean; + basicModeDirective?: string; defaultConfig: string; sizeX: number; sizeY: number; @@ -318,6 +320,7 @@ export interface DataKey extends KeyInfo { export enum DatasourceType { function = 'function', + device = 'device', entity = 'entity', entityCount = 'entityCount', alarmCount = 'alarmCount' @@ -326,6 +329,7 @@ export enum DatasourceType { export const datasourceTypeTranslationMap = new Map( [ [ DatasourceType.function, 'function.function' ], + [ DatasourceType.device, 'device.device' ], [ DatasourceType.entity, 'entity.entity' ], [ DatasourceType.entityCount, 'entity.entities-count' ], [ DatasourceType.alarmCount, 'entity.alarms-count' ] @@ -341,6 +345,7 @@ export interface Datasource { entityType?: EntityType; entityId?: string; entityName?: string; + deviceId?: string; entityAliasId?: string; filterId?: string; unresolvedStateEntity?: boolean; @@ -600,7 +605,13 @@ export interface WidgetSettings { [key: string]: any; } +export enum WidgetConfigMode { + basic = 'basic', + advanced = 'advanced' +} + export interface WidgetConfig { + configMode?: WidgetConfigMode; title?: string; titleIcon?: string; showTitle?: boolean; 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 3496b5e65b..7f0a8ffdcb 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3997,6 +3997,10 @@ "settings-form-selector": "Settings form selector", "data-key-settings-form-selector": "Data key settings form selector", "latest-data-key-settings-form-selector": "Latest data key settings form selector", + "has-basic-mode": "Has basic mode", + "basic-mode-form-selector": "Basic mode form selector", + "basic-mode": "Basic", + "advanced-mode": "Advanced", "javascript": "Javascript", "js": "JS", "remove-widget-type-title": "Are you sure you want to remove the widget type '{{widgetName}}'?", From adcf23cabbff4f98e53953ff3cab2aed1e5e4e04 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 25 May 2023 17:13:59 +0300 Subject: [PATCH 087/207] Improved the procedure of rule node update --- .../server/ThingsboardInstallApplication.java | 1 - .../controller/RuleChainController.java | 2 +- .../bean/AnnotationBeanDiscoveryService.java | 45 ---------- .../AnnotationComponentDiscoveryService.java | 87 +++++++++++++------ .../component/ComponentDiscoveryService.java | 6 ++ .../RuleNodeClassInfo.java} | 25 ++++-- .../service/install/InstallScripts.java | 3 +- .../update/DefaultDataUpdateService.java | 36 ++------ .../rule/DefaultTbRuleChainService.java | 50 ++++++++++- .../service/rule/TbRuleChainService.java | 3 + .../impl/RuleChainImportService.java | 4 +- .../controller/RuleChainControllerTest.java | 12 +-- ...AbstractRuleEngineFlowIntegrationTest.java | 5 ++ ...actRuleEngineLifecycleIntegrationTest.java | 2 + .../sync/ie/BaseExportImportServiceTest.java | 9 +- .../server/dao/rule/RuleChainService.java | 5 +- .../server/dao/rule/BaseRuleChainService.java | 40 ++------- .../server/dao/service/EdgeServiceTest.java | 3 +- .../dao/service/RuleChainServiceTest.java | 9 +- .../thingsboard/rule/engine/api/RuleNode.java | 2 + .../rule/engine/api/TbVersionedNode.java | 2 - .../metadata/TbAbstractNodeWithFetchTo.java | 5 -- .../TbFetchDeviceCredentialsNode.java | 1 + .../engine/metadata/TbGetAttributesNode.java | 1 + .../metadata/TbGetCustomerAttributeNode.java | 1 + .../metadata/TbGetCustomerDetailsNode.java | 1 + .../engine/metadata/TbGetDeviceAttrNode.java | 1 + .../metadata/TbGetOriginatorFieldsNode.java | 1 + .../metadata/TbGetRelatedAttributeNode.java | 1 + .../metadata/TbGetTenantAttributeNode.java | 1 + .../metadata/TbGetTenantDetailsNode.java | 1 + 31 files changed, 198 insertions(+), 167 deletions(-) delete mode 100644 application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java rename application/src/main/java/org/thingsboard/server/service/{bean/BeanDiscoveryService.java => component/RuleNodeClassInfo.java} (55%) diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java index b99674f416..b780f0e8cd 100644 --- a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java +++ b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java @@ -27,7 +27,6 @@ import java.util.Arrays; @Slf4j @SpringBootConfiguration @ComponentScan({"org.thingsboard.server.install", - "org.thingsboard.server.service.bean", "org.thingsboard.server.service.component", "org.thingsboard.server.service.install", "org.thingsboard.server.service.security.auth.jwt.settings", diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index 50abb3de1d..e43a365cf8 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -460,7 +460,7 @@ public class RuleChainController extends BaseController { @ApiParam(value = "Enables overwrite for existing rule chains with the same name.") @RequestParam(required = false, defaultValue = "false") boolean overwrite) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); - List importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, overwrite); + List importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, overwrite, tbRuleChainService::updateRuleNodeConfiguration); for (RuleChainImportResult importResult : importResults) { if (importResult.getError() == null) { tbClusterService.broadcastEntityStateChangeEvent(importResult.getTenantId(), importResult.getRuleChainId(), diff --git a/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java deleted file mode 100644 index 3ee1c14540..0000000000 --- a/application/src/main/java/org/thingsboard/server/service/bean/AnnotationBeanDiscoveryService.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.service.bean; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; -import org.springframework.core.type.filter.AnnotationTypeFilter; -import org.springframework.stereotype.Service; - -import java.lang.annotation.Annotation; -import java.util.HashSet; -import java.util.Set; - -@Service -public class AnnotationBeanDiscoveryService implements BeanDiscoveryService { - - @Value("${plugins.scan_packages}") - private String[] scanPackages; - - @Override - public Set discoverBeansByAnnotationType(Class annotationType) { - ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); - scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType)); - Set defs = new HashSet<>(); - for (String scanPackage : scanPackages) { - defs.addAll(scanner.findCandidateComponents(scanPackage)); - } - return defs; - } - -} diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index ac24141dcf..ad65ee805b 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -19,9 +19,12 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.env.Environment; import org.springframework.core.env.Profiles; +import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.NodeConfiguration; @@ -34,17 +37,19 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.dao.component.ComponentDescriptorService; -import org.thingsboard.server.service.bean.BeanDiscoveryService; import javax.annotation.PostConstruct; +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; @Service @Slf4j @@ -52,20 +57,22 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe public static final int MAX_OPTIMISITC_RETRIES = 3; + @Value("${plugins.scan_packages}") + private String[] scanPackages; + @Autowired private Environment environment; - @Autowired(required = false) - private BeanDiscoveryService beanDiscoveryService; - @Autowired private ComponentDescriptorService componentDescriptorService; - private Map components = new HashMap<>(); + private final Map ruleNodeClasses = new HashMap<>(); + + private final Map components = new HashMap<>(); - private Map> coreComponentsMap = new HashMap<>(); + private final Map> coreComponentsMap = new HashMap<>(); - private Map> edgeComponentsMap = new HashMap<>(); + private final Map> edgeComponentsMap = new HashMap<>(); private boolean isInstall() { return environment.acceptsProfiles(Profiles.of("install")); @@ -73,28 +80,62 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe @PostConstruct public void init() { + for (var def : discoverBeansByAnnotationType(RuleNode.class)) { + String clazzName = def.getBeanClassName(); + try { + var clazz = Class.forName(clazzName); + RuleNode annotation = clazz.getAnnotation(RuleNode.class); + boolean versioned = false; + if (annotation.version() > 0) { // No need to process nodes that has version = 0; + if (TbVersionedNode.class.isAssignableFrom(clazz)) { + versioned = true; + } else { + log.error("RuleNode [{}] has version {} but does not implement TbVersionedNode interface! Any update procedures for this rule node will be skipped!", clazzName, annotation.version()); + } + } + ruleNodeClasses.put(clazzName, new RuleNodeClassInfo(clazz, annotation, versioned)); + } catch (Exception e) { + log.warn("Failed to create instance of rule node type: {} due to: ", clazzName, e); + } + } if (!isInstall()) { discoverComponents(); } } + private Set discoverBeansByAnnotationType(Class annotationType) { + ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); + scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType)); + Set defs = new HashSet<>(); + for (String scanPackage : scanPackages) { + defs.addAll(scanner.findCandidateComponents(scanPackage)); + } + return defs; + } + + @Override + public Optional getRuleNodeInfo(String clazz) { + return Optional.ofNullable(ruleNodeClasses.get(clazz)); + } + + @Override + public List getVersionedNodes() { + return ruleNodeClasses.values().stream().filter(RuleNodeClassInfo::isVersioned).collect(Collectors.toList()); + } + private void registerRuleNodeComponents() { - Set ruleNodeBeanDefinitions = beanDiscoveryService.discoverBeansByAnnotationType(RuleNode.class); - for (BeanDefinition def : ruleNodeBeanDefinitions) { + for (RuleNodeClassInfo def : ruleNodeClasses.values()) { int retryCount = 0; Exception cause = null; while (retryCount < MAX_OPTIMISITC_RETRIES) { try { - String clazzName = def.getBeanClassName(); - Class clazz = Class.forName(clazzName); - RuleNode ruleNodeAnnotation = clazz.getAnnotation(RuleNode.class); - ComponentType type = ruleNodeAnnotation.type(); + ComponentType type = def.getAnnotation().type(); ComponentDescriptor component = scanAndPersistComponent(def, type); components.put(component.getClazz(), component); - putComponentIntoMaps(type, ruleNodeAnnotation, component); + putComponentIntoMaps(type, def.getAnnotation(), component); break; } catch (Exception e) { - log.trace("Can't initialize component {}, due to {}", def.getBeanClassName(), e.getMessage(), e); + log.trace("Can't initialize component {}, due to {}", def.getClassName(), e.getMessage(), e); cause = e; retryCount++; try { @@ -105,7 +146,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe } } if (cause != null && retryCount == MAX_OPTIMISITC_RETRIES) { - log.error("Can't initialize component {}, due to {}", def.getBeanClassName(), cause.getMessage(), cause); + log.error("Can't initialize component {}, due to {}", def.getClassName(), cause.getMessage(), cause); throw new RuntimeException(cause); } } @@ -142,18 +183,14 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe return false; } - private ComponentDescriptor scanAndPersistComponent(BeanDefinition def, ComponentType type) { + private ComponentDescriptor scanAndPersistComponent(RuleNodeClassInfo def, ComponentType type) { ComponentDescriptor scannedComponent = new ComponentDescriptor(); - String clazzName = def.getBeanClassName(); + String clazzName = def.getClassName(); try { scannedComponent.setType(type); - Class clazz = Class.forName(clazzName); + Class clazz = def.getClazz(); RuleNode ruleNodeAnnotation = clazz.getAnnotation(RuleNode.class); - if (TbVersionedNode.class.isAssignableFrom(clazz)) { - TbVersionedNode tbVersionNode = (TbVersionedNode) clazz.getDeclaredConstructor().newInstance(); - int currentVersion = tbVersionNode.getCurrentVersion(); - scannedComponent.setConfigurationVersion(currentVersion); - } + scannedComponent.setConfigurationVersion(def.isVersioned() ? def.getCurrentVersion() : 0); scannedComponent.setName(ruleNodeAnnotation.name()); scannedComponent.setScope(ruleNodeAnnotation.scope()); scannedComponent.setClusteringMode(ruleNodeAnnotation.clusteringMode()); @@ -165,7 +202,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe scannedComponent.setClazz(clazzName); log.debug("Processing scanned component: {}", scannedComponent); } catch (Exception e) { - log.error("Can't initialize component {}, due to {}", def.getBeanClassName(), e.getMessage(), e); + log.error("Can't initialize component {}, due to {}", clazzName, e.getMessage(), e); throw new RuntimeException(e); } ComponentDescriptor persistedComponent = componentDescriptorService.findByClazz(TenantId.SYS_TENANT_ID, clazzName); diff --git a/application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java index 731009575d..d0b0804f9b 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java @@ -19,7 +19,9 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; +import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; @@ -30,6 +32,10 @@ public interface ComponentDiscoveryService { void discoverComponents(); + Optional getRuleNodeInfo(String clazz); + + List getVersionedNodes(); + List getComponents(ComponentType type, RuleChainType ruleChainType); List getComponents(Set types, RuleChainType ruleChainType); diff --git a/application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/RuleNodeClassInfo.java similarity index 55% rename from application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java rename to application/src/main/java/org/thingsboard/server/service/component/RuleNodeClassInfo.java index 5ca615a94d..56fd367820 100644 --- a/application/src/main/java/org/thingsboard/server/service/bean/BeanDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/RuleNodeClassInfo.java @@ -13,15 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.service.bean; +package org.thingsboard.server.service.component; -import org.springframework.beans.factory.config.BeanDefinition; +import lombok.Data; +import org.thingsboard.rule.engine.api.RuleNode; -import java.lang.annotation.Annotation; -import java.util.Set; +@Data +public class RuleNodeClassInfo { -public interface BeanDiscoveryService { + private final Class clazz; + private final RuleNode annotation; + private final boolean versioned; - Set discoverBeansByAnnotationType(Class annotationType); + public String getClassName(){ + return clazz.getName(); + } + + public String getSimpleName() { + return clazz.getSimpleName(); + } + + public int getCurrentVersion() { + return annotation.version(); + } } diff --git a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java index 9a810aa446..36ec2b9b78 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java +++ b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java @@ -48,6 +48,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; import java.util.Optional; +import java.util.function.Function; import static org.thingsboard.server.utils.LwM2mObjectModelUtils.toLwm2mResource; @@ -173,7 +174,7 @@ public class InstallScripts { ruleChain = ruleChainService.saveRuleChain(ruleChain); ruleChainMetaData.setRuleChainId(ruleChain.getId()); - ruleChainService.saveRuleChainMetaData(TenantId.SYS_TENANT_ID, ruleChainMetaData); + ruleChainService.saveRuleChainMetaData(TenantId.SYS_TENANT_ID, ruleChainMetaData, Function.identity()); return ruleChain; } diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index d0f3bbdeb3..f832b04c21 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -81,7 +81,7 @@ import org.thingsboard.server.dao.sql.device.DeviceProfileRepository; import org.thingsboard.server.dao.tenant.TenantProfileService; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.timeseries.TimeseriesService; -import org.thingsboard.server.service.bean.BeanDiscoveryService; +import org.thingsboard.server.service.component.ComponentDiscoveryService; import org.thingsboard.server.service.install.InstallScripts; import org.thingsboard.server.service.install.SystemDataLoaderService; @@ -92,6 +92,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; import java.util.stream.Collectors; import static org.thingsboard.server.common.data.StringUtils.isBlank; @@ -139,7 +140,7 @@ public class DefaultDataUpdateService implements DataUpdateService { private QueueService queueService; @Autowired - private BeanDiscoveryService beanDiscoveryService; + private ComponentDiscoveryService componentDiscoveryService; @Autowired private SystemDataLoaderService systemDataLoaderService; @@ -221,11 +222,12 @@ public class DefaultDataUpdateService implements DataUpdateService { public void upgradeRuleNodes() { try { log.info("Lookup rule nodes to upgrade ..."); - var nodeClassToVersionMap = getNodeClassToVersionMap(); + var nodeClassToVersionMap = componentDiscoveryService.getVersionedNodes(); log.info("Found {} versioned nodes to check for upgrade!", nodeClassToVersionMap.size()); - nodeClassToVersionMap.forEach((clazz, toVersion) -> { - var ruleNodeType = clazz.getName(); + nodeClassToVersionMap.forEach(clazz -> { + var ruleNodeType = clazz.getClassName(); var ruleNodeTypeForLogs = clazz.getSimpleName(); + var toVersion = clazz.getCurrentVersion(); log.info("Going to check for nodes with type: {} to upgrade to version: {}.", ruleNodeTypeForLogs, toVersion); var ruleNodesToUpdate = new PageDataIterable<>( pageLink -> ruleChainService.findAllRuleNodesByTypeAndVersionLessThan(ruleNodeType, toVersion, pageLink), 1024 @@ -240,7 +242,7 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", ruleNodeId, ruleNodeTypeForLogs, fromVersion, toVersion); try { - var tbVersionedNode = (TbVersionedNode) clazz.getDeclaredConstructor().newInstance(); + var tbVersionedNode = (TbVersionedNode) clazz.getClazz().getDeclaredConstructor().newInstance(); TbPair upgradeRuleNodeConfigurationResult = tbVersionedNode.upgrade(fromVersion, oldConfiguration); if (upgradeRuleNodeConfigurationResult.getFirst()) { ruleNode.setConfiguration(upgradeRuleNodeConfigurationResult.getSecond()); @@ -262,26 +264,6 @@ public class DefaultDataUpdateService implements DataUpdateService { } } - private Map, Integer> getNodeClassToVersionMap() { - var ruleNodeDefinitions = beanDiscoveryService.discoverBeansByAnnotationType( - org.thingsboard.rule.engine.api.RuleNode.class - ); - var tbVersionedNodes = new HashMap, Integer>(); - for (var def : ruleNodeDefinitions) { - String clazzName = def.getBeanClassName(); - try { - var clazz = Class.forName(clazzName); - if (TbVersionedNode.class.isAssignableFrom(clazz)) { - TbVersionedNode tbVersionedNode = (TbVersionedNode) clazz.getDeclaredConstructor().newInstance(); - tbVersionedNodes.put(clazz, tbVersionedNode.getCurrentVersion()); - } - } catch (Exception e) { - log.warn("Failed to create instance of rule node type: {} due to: ", clazzName, e); - } - } - return tbVersionedNodes; - } - private final PaginatedUpdater deviceProfileEntityDynamicConditionsUpdater = new PaginatedUpdater<>() { @@ -516,7 +498,7 @@ public class DefaultDataUpdateService implements DataUpdateService { md.getNodes().add(ruleNode); md.setFirstNodeIndex(newIdx); md.addConnectionInfo(newIdx, oldIdx, "Success"); - ruleChainService.saveRuleChainMetaData(tenant.getId(), md); + ruleChainService.saveRuleChainMetaData(tenant.getId(), md, Function.identity()); } } catch (Exception e) { log.error("[{}] Unable to update Tenant: {}", tenant.getId(), tenant.getName(), e); diff --git a/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java b/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java index c2e425e14a..5756101ee1 100644 --- a/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java +++ b/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java @@ -15,10 +15,13 @@ */ package org.thingsboard.server.service.rule; +import com.fasterxml.jackson.databind.JsonNode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.rule.engine.api.TbVersionedNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNode; import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; import org.thingsboard.rule.engine.flow.TbRuleChainOutputNode; @@ -42,12 +45,13 @@ import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainUpdateResult; import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.rule.RuleNodeUpdateResult; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.component.ComponentDiscoveryService; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.install.InstallScripts; -import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; import java.util.ArrayList; import java.util.Collections; @@ -70,8 +74,7 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement private final RuleChainService ruleChainService; private final RelationService relationService; private final InstallScripts installScripts; - - private final EntitiesVersionControlService vcService; + private final ComponentDiscoveryService componentDiscoveryService; @Override public Set getRuleChainOutputLabels(TenantId tenantId, RuleChainId ruleChainId) { @@ -277,7 +280,7 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement RuleChainId ruleChainId = ruleChain.getId(); RuleChainId ruleChainMetaDataId = ruleChainMetaData.getRuleChainId(); try { - RuleChainUpdateResult result = ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData); + RuleChainUpdateResult result = ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData, this::updateRuleNodeConfiguration); checkNotNull(result.isSuccess() ? true : null); List updatedRuleChains; @@ -404,6 +407,45 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement } } + @Override + public RuleNode updateRuleNodeConfiguration(RuleNode node) { + var ruleChainId = node.getRuleChainId(); + var ruleNodeId = node.getId(); + var ruleNodeType = node.getType(); + try { + var ruleNodeClass = componentDiscoveryService.getRuleNodeInfo(ruleNodeType) + .orElseThrow(() -> new RuntimeException("Rule node " + ruleNodeType + " is not supported!")); + if (ruleNodeClass.isVersioned()) { + TbVersionedNode tbVersionedNode = (TbVersionedNode) ruleNodeClass.getClazz().getDeclaredConstructor().newInstance(); + int fromVersion = node.getConfigurationVersion(); + int toVersion = ruleNodeClass.getCurrentVersion(); + if (fromVersion < toVersion) { + log.debug("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", + ruleNodeId, ruleNodeType, fromVersion, toVersion); + try { + TbPair upgradeResult = tbVersionedNode.upgrade(fromVersion, node.getConfiguration()); + if (upgradeResult.getFirst()) { + node.setConfiguration(upgradeResult.getSecond()); + } + node.setConfigurationVersion(toVersion); + log.debug("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}", + ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion); + } catch (TbNodeException e) { + log.warn("Failed to upgrade rule node with id: {} type: {} rule chain id: {} fromVersion: {} toVersion: {} due to: ", + ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion, e); + } + } else { + log.debug("Rule node with id: {} type: {} ruleChainId: {} already set to latest version!", + ruleNodeId, ruleChainId, ruleNodeType); + } + } + } catch (Exception e) { + log.error("Failed to update the rule node with id: {} type: {}, rule chain id: {}", + ruleNodeId, ruleNodeType, ruleChainId, e); + } + return node; + } + private Set updateRelatedRuleChains(TenantId tenantId, RuleChainId ruleChainId, Map labelsMap) { Set updatedRuleChains = new HashSet<>(); List usageList = getOutputLabelUsage(tenantId, ruleChainId); diff --git a/application/src/main/java/org/thingsboard/server/service/rule/TbRuleChainService.java b/application/src/main/java/org/thingsboard/server/service/rule/TbRuleChainService.java index 02b79544f4..17f1338bba 100644 --- a/application/src/main/java/org/thingsboard/server/service/rule/TbRuleChainService.java +++ b/application/src/main/java/org/thingsboard/server/service/rule/TbRuleChainService.java @@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainOutputLabelsUsage; import org.thingsboard.server.common.data.rule.RuleChainUpdateResult; +import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.service.entitiy.SimpleTbEntityService; import java.util.List; @@ -54,4 +55,6 @@ public interface TbRuleChainService extends SimpleTbEntityService { RuleChain setAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChain ruleChain, User user) throws ThingsboardException; RuleChain unsetAutoAssignToEdgeRuleChain(TenantId tenantId, RuleChain ruleChain, User user) throws ThingsboardException; + + RuleNode updateRuleNodeConfiguration(RuleNode ruleNode); } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java index eb54fce21e..021522986d 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.sync.ie.RuleChainExportData; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.rule.RuleNodeDao; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.rule.TbRuleChainService; import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx; import java.util.Arrays; @@ -52,6 +53,7 @@ public class RuleChainImportService extends BaseEntityImportService HINTS = new LinkedHashSet<>(Arrays.asList(EntityType.RULE_CHAIN, EntityType.DEVICE, EntityType.ASSET)); + private final TbRuleChainService tbRuleChainService; private final RuleChainService ruleChainService; private final RuleNodeDao ruleNodeDao; @@ -106,7 +108,7 @@ public class RuleChainImportService extends BaseEntityImportService 0); Assert.assertEquals(ruleChain.getName(), savedRuleChain.getName()); - TbVersionedNode tbVersionedNode = new TbGetRelatedAttributeNode(); - String ruleNodeType = tbVersionedNode.getClass().getName(); - int currentVersion = tbVersionedNode.getCurrentVersion(); + var annotation = TbGetRelatedAttributeNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class); + String ruleNodeType = TbGetRelatedAttributeNode.class.getName(); + int currentVersion = annotation.version(); String oldConfig = "{\"attrMapping\":{\"serialNumber\":\"sn\"}," + "\"relationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1," + "\"filters\":[{\"relationType\":\"Contains\",\"entityTypes\":[]}]," + "\"fetchLastLevelOnly\":false},\"telemetry\":false}"; - String newConfig = JacksonUtil.toString(new TbGetRelatedDataNodeConfiguration().defaultConfiguration()); + TbGetRelatedDataNodeConfiguration defaultConfiguration = new TbGetRelatedDataNodeConfiguration().defaultConfiguration(); + String newConfig = JacksonUtil.toString(defaultConfiguration); var ruleChainMetaData = createRuleChainMetadataWithTbVersionedNodes( ruleChainId, @@ -170,7 +172,7 @@ public class RuleChainControllerTest extends AbstractControllerTest { for (RuleNode ruleNode : savedRuleChainMetaData.getNodes()) { Assert.assertNotNull(ruleNode.getId()); Assert.assertEquals(currentVersion, ruleNode.getConfigurationVersion()); - Assert.assertEquals(JacksonUtil.toJsonNode(newConfig), ruleNode.getConfiguration()); + Assert.assertEquals(defaultConfiguration, JacksonUtil.treeToValue(ruleNode.getConfiguration(), defaultConfiguration.getClass())); } } diff --git a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java index f2079d5d65..6c2e5e9c5e 100644 --- a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java @@ -28,6 +28,7 @@ import org.springframework.test.util.ReflectionTestUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.flow.TbRuleChainInputNodeConfiguration; import org.thingsboard.rule.engine.metadata.FetchTo; +import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.common.data.DataConstants; @@ -138,6 +139,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule RuleNode ruleNode1 = new RuleNode(); ruleNode1.setName("Simple Rule Node 1"); ruleNode1.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName()); + ruleNode1.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version()); ruleNode1.setDebugMode(true); TbGetAttributesNodeConfiguration configuration1 = new TbGetAttributesNodeConfiguration(); configuration1.setFetchTo(FetchTo.METADATA); @@ -147,6 +149,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule RuleNode ruleNode2 = new RuleNode(); ruleNode2.setName("Simple Rule Node 2"); ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName()); + ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version()); ruleNode2.setDebugMode(true); TbGetAttributesNodeConfiguration configuration2 = new TbGetAttributesNodeConfiguration(); configuration2.setFetchTo(FetchTo.METADATA); @@ -242,6 +245,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule RuleNode ruleNode1 = new RuleNode(); ruleNode1.setName("Simple Rule Node 1"); ruleNode1.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName()); + ruleNode1.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version()); ruleNode1.setDebugMode(true); TbGetAttributesNodeConfiguration configuration1 = new TbGetAttributesNodeConfiguration(); configuration1.setFetchTo(FetchTo.METADATA); @@ -275,6 +279,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule RuleNode ruleNode2 = new RuleNode(); ruleNode2.setName("Simple Rule Node 2"); ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName()); + ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version()); ruleNode2.setDebugMode(true); TbGetAttributesNodeConfiguration configuration2 = new TbGetAttributesNodeConfiguration(); configuration2.setFetchTo(FetchTo.METADATA); diff --git a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java index e914511ceb..9753f06aff 100644 --- a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java @@ -25,6 +25,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.metadata.FetchTo; +import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.common.data.DataConstants; @@ -93,6 +94,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac RuleNode ruleNode = new RuleNode(); ruleNode.setName("Simple Rule Node"); ruleNode.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName()); + ruleNode.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version()); ruleNode.setDebugMode(true); TbGetAttributesNodeConfiguration configuration = new TbGetAttributesNodeConfiguration(); configuration.setFetchTo(FetchTo.METADATA); diff --git a/application/src/test/java/org/thingsboard/server/service/sync/ie/BaseExportImportServiceTest.java b/application/src/test/java/org/thingsboard/server/service/sync/ie/BaseExportImportServiceTest.java index aa15b1da4c..39b61c6c47 100644 --- a/application/src/test/java/org/thingsboard/server/service/sync/ie/BaseExportImportServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/sync/ie/BaseExportImportServiceTest.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.debug.TbMsgGeneratorNode; import org.thingsboard.rule.engine.debug.TbMsgGeneratorNodeConfiguration; +import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; @@ -86,6 +87,7 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Collections; import java.util.UUID; +import java.util.function.Function; import static org.assertj.core.api.Assertions.assertThat; @@ -333,6 +335,7 @@ public abstract class BaseExportImportServiceTest extends AbstractControllerTest RuleNode ruleNode2 = new RuleNode(); ruleNode2.setName("Simple Rule Node 2"); ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName()); + ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version()); ruleNode2.setDebugMode(true); TbGetAttributesNodeConfiguration configuration2 = new TbGetAttributesNodeConfiguration(); configuration2.setServerAttributeNames(Collections.singletonList("serverAttributeKey2")); @@ -341,7 +344,7 @@ public abstract class BaseExportImportServiceTest extends AbstractControllerTest metaData.setNodes(Arrays.asList(ruleNode1, ruleNode2)); metaData.setFirstNodeIndex(0); metaData.addConnectionInfo(0, 1, "Success"); - ruleChainService.saveRuleChainMetaData(tenantId, metaData); + ruleChainService.saveRuleChainMetaData(tenantId, metaData, Function.identity()); return ruleChainService.findRuleChainById(tenantId, ruleChain.getId()); } @@ -361,6 +364,7 @@ public abstract class BaseExportImportServiceTest extends AbstractControllerTest RuleNode ruleNode1 = new RuleNode(); ruleNode1.setName("Simple Rule Node 1"); ruleNode1.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName()); + ruleNode1.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version()); ruleNode1.setDebugMode(true); TbGetAttributesNodeConfiguration configuration1 = new TbGetAttributesNodeConfiguration(); configuration1.setServerAttributeNames(Collections.singletonList("serverAttributeKey1")); @@ -369,6 +373,7 @@ public abstract class BaseExportImportServiceTest extends AbstractControllerTest RuleNode ruleNode2 = new RuleNode(); ruleNode2.setName("Simple Rule Node 2"); ruleNode2.setType(org.thingsboard.rule.engine.metadata.TbGetAttributesNode.class.getName()); + ruleNode2.setConfigurationVersion(TbGetAttributesNode.class.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class).version()); ruleNode2.setDebugMode(true); TbGetAttributesNodeConfiguration configuration2 = new TbGetAttributesNodeConfiguration(); configuration2.setServerAttributeNames(Collections.singletonList("serverAttributeKey2")); @@ -377,7 +382,7 @@ public abstract class BaseExportImportServiceTest extends AbstractControllerTest metaData.setNodes(Arrays.asList(ruleNode1, ruleNode2)); metaData.setFirstNodeIndex(0); metaData.addConnectionInfo(0, 1, "Success"); - ruleChainService.saveRuleChainMetaData(tenantId, metaData); + ruleChainService.saveRuleChainMetaData(tenantId, metaData, Function.identity()); return ruleChainService.findRuleChainById(tenantId, ruleChain.getId()); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index 612be9087b..95cdc0e02d 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -35,6 +35,7 @@ import org.thingsboard.server.dao.entity.EntityDaoService; import java.util.Collection; import java.util.List; +import java.util.function.Function; /** * Created by igor on 3/12/18. @@ -45,7 +46,7 @@ public interface RuleChainService extends EntityDaoService { boolean setRootRuleChain(TenantId tenantId, RuleChainId ruleChainId); - RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData); + RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function ruleNodeUpdater); RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId); @@ -75,7 +76,7 @@ public interface RuleChainService extends EntityDaoService { RuleChainData exportTenantRuleChains(TenantId tenantId, PageLink pageLink) throws ThingsboardException; - List importTenantRuleChains(TenantId tenantId, RuleChainData ruleChainData, boolean overwrite); + List importTenantRuleChains(TenantId tenantId, RuleChainData ruleChainData, boolean overwrite, Function ruleNodeUpdater); RuleChain assignRuleChainToEdge(TenantId tenantId, RuleChainId ruleChainId, EdgeId edgeId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java index 8e0789a5c1..56e6969c9a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java @@ -73,6 +73,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import static org.thingsboard.server.common.data.DataConstants.TENANT; @@ -145,7 +146,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } @Override - public RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData) { + public RuleChainUpdateResult saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData, Function ruleNodeUpdater) { Validator.validateId(ruleChainMetaData.getRuleChainId(), "Incorrect rule chain id."); RuleChain ruleChain = findRuleChainById(tenantId, ruleChainMetaData.getRuleChainId()); if (ruleChain == null) { @@ -189,38 +190,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC if (nodes != null) { for (RuleNode node : toAddOrUpdate) { node.setRuleChainId(ruleChainId); - String ruleNodeType = node.getType(); - RuleNodeId ruleNodeId = node.getId(); - try { - var ruleNodeClazz = Class.forName(ruleNodeType); - if (TbVersionedNode.class.isAssignableFrom(ruleNodeClazz)) { - TbVersionedNode tbVersionedNode = (TbVersionedNode) ruleNodeClazz.getDeclaredConstructor().newInstance(); - int fromVersion = node.getConfigurationVersion(); - int toVersion = tbVersionedNode.getCurrentVersion(); - if (fromVersion < toVersion) { - log.debug("Going to upgrade rule node with id: {} type: {} fromVersion: {} toVersion: {}", - ruleNodeId, ruleNodeType, fromVersion, toVersion); - try { - TbPair upgradeResult = tbVersionedNode.upgrade(fromVersion, node.getConfiguration()); - if (upgradeResult.getFirst()) { - node.setConfiguration(upgradeResult.getSecond()); - } - node.setConfigurationVersion(toVersion); - log.debug("Successfully upgrade rule node with id: {} type: {}, rule chain id: {} fromVersion: {} toVersion: {}", - ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion); - } catch (TbNodeException e) { - log.warn("Failed to upgrade rule node with id: {} type: {} rule chain id: {} fromVersion: {} toVersion: {} due to: ", - ruleNodeId, ruleNodeType, ruleChainId, fromVersion, toVersion, e); - } - } else { - log.debug("Rule node with id: {} type: {} ruleChainId: {} already set to latest version!", - ruleNodeId, ruleChainId, ruleNodeType); - } - } - } catch (Exception e) { - log.error("Failed to create instance of rule node with id: {} type: {}, rule chain id: {}", - ruleNodeId, ruleNodeType, ruleChainId); - } + node = ruleNodeUpdater.apply(node); RuleNode savedNode = ruleNodeDao.save(tenantId, node); relations.add(new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); @@ -484,7 +454,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } @Override - public List importTenantRuleChains(TenantId tenantId, RuleChainData ruleChainData, boolean overwrite) { + public List importTenantRuleChains(TenantId tenantId, RuleChainData ruleChainData, boolean overwrite, Function ruleNodeUpdater) { List importResults = new ArrayList<>(); setRandomRuleChainIds(ruleChainData); @@ -521,7 +491,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC } if (CollectionUtils.isNotEmpty(ruleChainData.getMetadata())) { - ruleChainData.getMetadata().forEach(md -> saveRuleChainMetaData(tenantId, md)); + ruleChainData.getMetadata().forEach(md -> saveRuleChainMetaData(tenantId, md, ruleNodeUpdater)); } return importResults; diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/EdgeServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/EdgeServiceTest.java index 02515dcfbe..adeb543625 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/EdgeServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/EdgeServiceTest.java @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.function.Function; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @@ -639,7 +640,7 @@ public class EdgeServiceTest extends AbstractServiceTest { ruleChainMetaData3.setNodes(Arrays.asList(ruleNode1, ruleNode2)); ruleChainMetaData3.setFirstNodeIndex(0); ruleChainMetaData3.setRuleChainId(ruleChain3.getId()); - ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData3); + ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData3, Function.identity()); ruleChainService.assignRuleChainToEdge(tenantId, ruleChain3.getId(), savedEdge.getId()); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/RuleChainServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/RuleChainServiceTest.java index e821a1e223..dd68e4ae76 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/RuleChainServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/RuleChainServiceTest.java @@ -40,6 +40,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.Function; /** * Created by igor on 3/13/18. @@ -280,7 +281,7 @@ public class RuleChainServiceTest extends AbstractServiceTest { ruleNodes.set(name3Index, ruleNode4); - Assert.assertTrue(ruleChainService.saveRuleChainMetaData(tenantId, savedRuleChainMetaData).isSuccess()); + Assert.assertTrue(ruleChainService.saveRuleChainMetaData(tenantId, savedRuleChainMetaData, Function.identity()).isSuccess()); RuleChainMetaData updatedRuleChainMetaData = ruleChainService.loadRuleChainMetaData(tenantId, savedRuleChainMetaData.getRuleChainId()); Assert.assertEquals(3, updatedRuleChainMetaData.getNodes().size()); @@ -311,14 +312,14 @@ public class RuleChainServiceTest extends AbstractServiceTest { @Test public void testUpdateRuleChainMetaDataWithCirclingRelation() { Assertions.assertThrows(DataValidationException.class, () -> { - ruleChainService.saveRuleChainMetaData(tenantId, createRuleChainMetadataWithCirclingRelation()); + ruleChainService.saveRuleChainMetaData(tenantId, createRuleChainMetadataWithCirclingRelation(), Function.identity()); }); } @Test public void testUpdateRuleChainMetaDataWithCirclingRelation2() { Assertions.assertThrows(DataValidationException.class, () -> { - ruleChainService.saveRuleChainMetaData(tenantId, createRuleChainMetadataWithCirclingRelation2()); + ruleChainService.saveRuleChainMetaData(tenantId, createRuleChainMetadataWithCirclingRelation2(), Function.identity()); }); } @@ -395,7 +396,7 @@ public class RuleChainServiceTest extends AbstractServiceTest { ruleChainMetaData.addConnectionInfo(0,2,"fail"); ruleChainMetaData.addConnectionInfo(1,2,"success"); - Assert.assertTrue(ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData).isSuccess()); + Assert.assertTrue(ruleChainService.saveRuleChainMetaData(tenantId, ruleChainMetaData, Function.identity()).isSuccess()); return ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId()); } diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java index 99d073df44..7ee61bac1d 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java @@ -65,4 +65,6 @@ public @interface RuleNode { RuleChainType[] ruleChainTypes() default {RuleChainType.CORE, RuleChainType.EDGE}; + int version() default 0; + } diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java index ce9a63111b..be9a5d01e2 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java @@ -22,6 +22,4 @@ public interface TbVersionedNode extends TbNode { TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException; - int getCurrentVersion(); - } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java index 924092ad87..16b51d02c0 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractNodeWithFetchTo.java @@ -41,11 +41,6 @@ public abstract class TbAbstractNodeWithFetchTo Date: Thu, 25 May 2023 18:35:53 +0300 Subject: [PATCH 088/207] Improve widget preview --- .../home/components/widget/widget-preview.component.html | 2 +- .../home/components/widget/widget-preview.component.ts | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html index 7d64036838..870cb08513 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html @@ -20,7 +20,7 @@ [stateController]="stateController" [widgets]="widgets" [autofillHeight]="true" - [columns]="20" + [columns]="24" [isEdit]="false" [isMobileDisabled]="true" [isEditActionEnabled]="false" diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts index 4b62bba653..cd088e5744 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.ts @@ -67,14 +67,11 @@ export class WidgetPreviewComponent extends PageComponent implements OnInit, OnC } private loadPreviewWidget() { - const sizeX = this.widget.sizeX * 2; - const sizeY = this.widget.sizeY * 2; - const col = Math.floor(Math.max(0, (20 - sizeX) / 2)); const widget = deepClone(this.widget); - widget.sizeX = sizeX; - widget.sizeY = sizeY; + widget.sizeX = 24; + widget.sizeY = this.widget.sizeY * 2; widget.row = 0; - widget.col = col; + widget.col = 0; widget.config = this.widgetConfig; this.widgets = [widget]; } From f657bd306b3452cef01e7d003ce7149b878c773b Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Thu, 25 May 2023 20:42:03 +0300 Subject: [PATCH 089/207] UI: Refactoring --- .../home/pages/rulechain/rulechain-page.component.html | 7 +++---- .../home/pages/rulechain/rulechain-page.component.scss | 7 +++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html index 85dd8df688..f018f15fab 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html @@ -15,9 +15,8 @@ limitations under the License. --> -
+
@@ -163,7 +162,7 @@ (click)="drawer.toggle();" matTooltip="{{ (drawer.opened ? 'rulenode.close-node-library' : 'rulenode.open-node-library') | translate }}" matTooltipPosition="above"> - chevron_right + chevron_right -
+
diff --git a/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss b/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss index 5713fa2461..a2d4232f24 100644 --- a/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss +++ b/ui-ngx/src/app/modules/home/components/relation/relation-filters.component.scss @@ -29,7 +29,7 @@ } .body { - max-height: 300px; + max-height: 363px; overflow: auto; .row { @@ -48,5 +48,9 @@ .any-filter{ margin: 10px 0 20px; } + + .add-button { + margin: 5px 0px 15px; + } } } diff --git a/ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.html b/ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.html index 909d780e45..3ad2ef2824 100644 --- a/ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.html +++ b/ui-ngx/src/app/shared/components/entity/entity-subtype-list.component.html @@ -15,8 +15,8 @@ limitations under the License. --> - - {{ label | translate }} + + {{ label }} + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.ts new file mode 100644 index 0000000000..02d9787aa7 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.ts @@ -0,0 +1,139 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormGroup +} from '@angular/forms'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { WidgetActionsData } from '@home/components/widget/action/manage-widget-actions.component.models'; +import { Datasource, WidgetActionDescriptor } from '@shared/models/widget.models'; +import { + ManageWidgetActionsDialogComponent, + ManageWidgetActionsDialogData +} from '@home/components/widget/action/manage-widget-actions-dialog.component'; +import { deepClone } from '@core/utils'; +import { MatDialog } from '@angular/material/dialog'; + +@Component({ + selector: 'tb-widget-actions-panel', + templateUrl: './widget-actions-panel.component.html', + styleUrls: ['../../widget-config.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => WidgetActionsPanelComponent), + multi: true + } + ] +}) +export class WidgetActionsPanelComponent implements ControlValueAccessor, OnInit { + + @Input() + disabled: boolean; + + actionsFormGroup: UntypedFormGroup; + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder, + private dialog: MatDialog, + private cd: ChangeDetectorRef, + private widgetConfigComponent: WidgetConfigComponent) { + } + + ngOnInit() { + this.actionsFormGroup = this.fb.group({ + actions: [null, []] + }); + this.actionsFormGroup.get('actions').valueChanges.subscribe( + (val) => this.propagateChange(val) + ); + } + + writeValue(actions?: {[actionSourceId: string]: Array}): void { + this.actionsFormGroup.get('actions').patchValue(actions || {}, {emitEvent: false}); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.actionsFormGroup.disable({emitEvent: false}); + } else { + this.actionsFormGroup.enable({emitEvent: false}); + } + } + + public get widgetActionSourceIds(): Array { + const actions: {[actionSourceId: string]: Array} = this.actionsFormGroup.get('actions').value; + return actions ? Object.keys(actions) : []; + } + + public widgetActionsByActionSourceId(actionSourceId: string): Array { + const actions: {[actionSourceId: string]: Array} = this.actionsFormGroup.get('actions').value; + return actions[actionSourceId] || []; + } + + public get hasWidgetActions(): boolean { + const actions: {[actionSourceId: string]: Array} = this.actionsFormGroup.get('actions').value; + if (actions) { + for (const actionSourceId of Object.keys(actions)) { + if (actions[actionSourceId] && actions[actionSourceId].length) { + return true; + } + } + } + return false; + } + + public manageWidgetActions() { + const actions: {[actionSourceId: string]: Array} = this.actionsFormGroup.get('actions').value; + const actionsData: WidgetActionsData = { + actionsMap: deepClone(actions), + actionSources: this.widgetConfigComponent.modelValue.actionSources || {} + }; + this.dialog.open}>(ManageWidgetActionsDialogComponent, { + disableClose: true, + panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], + data: { + widgetTitle: this.widgetConfigComponent.modelValue.widgetName, + callbacks: this.widgetConfigComponent.widgetConfigCallbacks, + actionsData, + widgetType: this.widgetConfigComponent.widgetType + } + }).afterClosed().subscribe( + (res) => { + if (res) { + this.actionsFormGroup.get('actions').patchValue(res); + this.cd.markForCheck(); + } + } + ); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-config.scss b/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-config.scss new file mode 100644 index 0000000000..d29594fce3 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-config.scss @@ -0,0 +1,20 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host { + display: flex; + flex-direction: column; + gap: 16px; +} diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-widget-config.module.ts new file mode 100644 index 0000000000..5d36fa43b3 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-widget-config.module.ts @@ -0,0 +1,49 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { NgModule, Type } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SharedModule } from '@shared/shared.module'; +import { IBasicWidgetConfigComponent } from '@home/components/widget/widget-config.component.models'; +import { WidgetConfigComponentsModule } from '@home/components/widget/widget-config-components.module'; +import { + SimpleCardBasicConfigComponent +} from '@home/components/widget/basic-config/cards/simple-card-basic-config.component'; +import { + WidgetActionsPanelComponent +} from '@home/components/widget/basic-config/action/widget-actions-panel.component'; + +@NgModule({ + declarations: [ + WidgetActionsPanelComponent, + SimpleCardBasicConfigComponent + ], + imports: [ + CommonModule, + SharedModule, + WidgetConfigComponentsModule + ], + exports: [ + WidgetActionsPanelComponent, + SimpleCardBasicConfigComponent + ] +}) +export class BasicWidgetConfigModule { +} + +export const basicWidgetConfigComponentsMap: {[key: string]: Type} = { + 'tb-simple-card-basic-config': SimpleCardBasicConfigComponent +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html new file mode 100644 index 0000000000..a686add2fd --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html @@ -0,0 +1,42 @@ + + + + +
+
widget-config.appearance
+
+
widgets.simple-card.label-position
+ + + + {{ 'widgets.simple-card.label-position-left' | translate }} + + + {{ 'widgets.simple-card.label-position-top' | translate }} + + + +
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts new file mode 100644 index 0000000000..f8cdaae59c --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts @@ -0,0 +1,58 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; + +@Component({ + selector: 'tb-simple-card-basic-config', + templateUrl: './simple-card-basic-config.component.html', + styleUrls: ['../basic-config.scss', '../../widget-config.scss'] +}) +export class SimpleCardBasicConfigComponent extends BasicWidgetConfigComponent { + + simpleCardWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + private fb: UntypedFormBuilder) { + super(store); + } + + protected configForm(): UntypedFormGroup { + return this.simpleCardWidgetConfigForm; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + this.simpleCardWidgetConfigForm = this.fb.group({ + datasources: [configData.config.datasources, []], + labelPosition: [configData.config.settings?.labelPosition, []], + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + this.widgetConfig.config.datasources = this.simpleCardWidgetConfigForm.value.datasources; + this.widgetConfig.config.actions = this.simpleCardWidgetConfigForm.value.actions; + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + this.widgetConfig.config.settings.labelPosition = this.simpleCardWidgetConfigForm.value.labelPosition; + return this.widgetConfig; + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.html b/ui-ngx/src/app/modules/home/components/widget/datasource.component.html index 40c63e6764..5cf519637b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasource.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/datasource.component.html @@ -16,7 +16,7 @@ -->
- + widget-config.datasource-type @@ -24,7 +24,7 @@ -
+
datasource.label @@ -53,13 +53,6 @@ formControlName="entityAliasId" [callbacks]="entityAliasSelectCallbacks"> - -
+ +
diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts b/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts index 3f521b1d91..79adc363a6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts @@ -30,7 +30,7 @@ import { DatasourceType, datasourceTypeTranslationMap, JsonSettingsSchema, - Widget, + Widget, WidgetConfigMode, widgetType } from '@shared/models/widget.models'; import { AlarmSearchStatus } from '@shared/models/alarm.models'; @@ -61,6 +61,10 @@ import { EntityType } from '@shared/models/entity-type.models'; }) export class DatasourceComponent implements ControlValueAccessor, OnInit, Validator { + public get basicMode(): boolean { + return !this.widgetConfigComponent.widgetEditMode && this.widgetConfigComponent.widgetConfigMode === WidgetConfigMode.basic; + } + public get widgetType(): widgetType { return this.widgetConfigComponent.widgetType; } diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.html b/ui-ngx/src/app/modules/home/components/widget/datasources.component.html index 98bbe96600..a5a8a89004 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasources.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/datasources.component.html @@ -17,11 +17,23 @@ -->
-
+
{{ (singleDatasource ? 'widget-config.datasource' : 'widget-config.datasources') | translate }}
{{ 'widget-config.timeseries-key-error' | translate }}
+ +
{{ 'widget-config.maximum-datasources' | translate:{count: maxDatasources} }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts b/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts index 7c1196a0c4..f47adfb2a9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts @@ -14,23 +14,33 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { Component, forwardRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { AbstractControl, - ControlValueAccessor, FormControl, + ControlValueAccessor, + FormControl, NG_VALIDATORS, - NG_VALUE_ACCESSOR, UntypedFormArray, - UntypedFormBuilder, UntypedFormControl, + NG_VALUE_ACCESSOR, + UntypedFormArray, + UntypedFormBuilder, + UntypedFormControl, UntypedFormGroup, Validator } from '@angular/forms'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; -import { Datasource, DatasourceType, JsonSettingsSchema, widgetType } from '@shared/models/widget.models'; +import { + Datasource, + DatasourceType, + JsonSettingsSchema, + WidgetConfigMode, + widgetType +} from '@shared/models/widget.models'; import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { deepClone } from '@core/utils'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { UtilsService } from '@core/services/utils.service'; import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'tb-datasources', @@ -49,7 +59,13 @@ import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.m } ] }) -export class DatasourcesComponent implements ControlValueAccessor, OnInit, Validator { +export class DatasourcesComponent implements ControlValueAccessor, OnInit, Validator, OnChanges { + + datasourceType = DatasourceType; + + public get basicMode(): boolean { + return !this.widgetConfigComponent.widgetEditMode && this.configMode === WidgetConfigMode.basic; + } public get maxDatasources(): number { return this.widgetConfigComponent.modelValue?.typeParameters?.maxDatasources; @@ -71,16 +87,22 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid @Input() disabled: boolean; + @Input() + configMode: WidgetConfigMode; + datasourcesFormGroup: UntypedFormGroup; timeseriesKeyError = false; datasourceError: string[] = []; + datasourcesMode: DatasourceType; + private propagateChange = (_val: any) => {}; constructor(private fb: UntypedFormBuilder, private utils: UtilsService, + public translate: TranslateService, private widgetConfigComponent: WidgetConfigComponent) { } @@ -116,16 +138,38 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid ); } + ngOnChanges(changes: SimpleChanges): void { + for (const propName of Object.keys(changes)) { + const change = changes[propName]; + if (!change.firstChange && change.currentValue !== change.previousValue) { + if (propName === 'configMode') { + this.configModeChanged(); + } + } + } + } + writeValue(datasources?: Datasource[]): void { this.datasourcesFormArray.clear({emitEvent: false}); + this.datasourcesMode = this.detectDatasourcesMode(datasources); + let changed = false; if (datasources) { datasources.forEach((datasource) => { + if (this.basicMode && datasource.type !== this.datasourcesMode) { + datasource.type = this.datasourcesMode; + changed = true; + } this.datasourcesFormArray.push(this.fb.control(datasource, []), {emitEvent: false}); }); } if (this.singleDatasource && !this.datasourcesFormArray.length) { this.addDatasource(false); } + if (changed) { + setTimeout(() => { + this.datasourcesUpdated(this.datasourcesFormGroup.get('datasources').value); + }, 0); + } } validate(c: UntypedFormControl) { @@ -175,6 +219,37 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid return null; } + datasourcesModeChange(datasourcesMode: DatasourceType) { + this.datasourcesMode = datasourcesMode; + if (this.basicMode) { + for (const datasourceControl of this.datasourcesControls) { + const datasource: Datasource = datasourceControl.value; + if (datasource.type !== datasourcesMode) { + datasource.type = datasourcesMode; + datasourceControl.patchValue(datasource); + } + } + } + } + + private configModeChanged() { + if (this.basicMode) { + let datasourcesMode = this.detectDatasourcesMode(this.datasourcesFormGroup.get('datasources').value); + this.datasourcesModeChange(datasourcesMode); + } + } + + private detectDatasourcesMode(datasources?: Datasource[]) { + let datasourcesMode = DatasourceType.device; + if (datasources && datasources.length) { + datasourcesMode = datasources[0].type; + } + if (datasourcesMode !== DatasourceType.device && datasourcesMode !== DatasourceType.entity) { + datasourcesMode = DatasourceType.device; + } + return datasourcesMode; + } + get datasourcesFormArray(): UntypedFormArray { return this.datasourcesFormGroup.get('datasources') as UntypedFormArray; } @@ -207,7 +282,8 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid newDatasource = deepClone(this.utils.getDefaultDatasource(this.dataKeySettingsSchema.schema)); newDatasource.dataKeys = [this.dataKeysCallbacks.generateDataKey('Sin', DataKeyType.function, this.dataKeySettingsSchema)]; } else { - newDatasource = { type: DatasourceType.entity, + const type = this.basicMode ? this.datasourcesMode : DatasourceType.entity; + newDatasource = { type, dataKeys: [] }; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.html index 8b60b19007..1ee182f923 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.html @@ -15,16 +15,19 @@ limitations under the License. --> -
- - widgets.simple-card.label-position - - - {{ 'widgets.simple-card.label-position-left' | translate }} - - - {{ 'widgets.simple-card.label-position-top' | translate }} - - - -
+
+
widgets.simple-card.label
+
+
widgets.simple-card.label-position
+ + + + {{ 'widgets.simple-card.label-position-left' | translate }} + + + {{ 'widgets.simple-card.label-position-top' | translate }} + + + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts index 4ecd21ad1d..f22828d41d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts @@ -23,7 +23,7 @@ import { AppState } from '@core/core.state'; @Component({ selector: 'tb-simple-card-widget-settings', templateUrl: './simple-card-widget-settings.component.html', - styleUrls: [] + styleUrls: ['../../../widget-config.scss'] }) export class SimpleCardWidgetSettingsComponent extends WidgetSettingsComponent { diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config-components.module.ts new file mode 100644 index 0000000000..56302e212d --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config-components.module.ts @@ -0,0 +1,61 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SharedModule } from '@app/shared/shared.module'; +import { AlarmFilterConfigComponent } from '@home/components/alarm/alarm-filter-config.component'; +import { DataKeysComponent } from '@home/components/widget/data-keys.component'; +import { DataKeyConfigDialogComponent } from '@home/components/widget/data-key-config-dialog.component'; +import { DataKeyConfigComponent } from '@home/components/widget/data-key-config.component'; +import { DatasourceComponent } from '@home/components/widget/datasource.component'; +import { DatasourcesComponent } from '@home/components/widget/datasources.component'; +import { EntityAliasSelectComponent } from '@home/components/alias/entity-alias-select.component'; +import { FilterSelectComponent } from '@home/components/filter/filter-select.component'; +import { WidgetSettingsModule } from '@home/components/widget/lib/settings/widget-settings.module'; +import { WidgetSettingsComponent } from '@home/components/widget/widget-settings.component'; + +@NgModule({ + declarations: + [ + AlarmFilterConfigComponent, + DataKeysComponent, + DataKeyConfigDialogComponent, + DataKeyConfigComponent, + DatasourceComponent, + DatasourcesComponent, + EntityAliasSelectComponent, + FilterSelectComponent, + WidgetSettingsComponent + ], + imports: [ + CommonModule, + SharedModule, + WidgetSettingsModule + ], + exports: [ + AlarmFilterConfigComponent, + DataKeysComponent, + DataKeyConfigDialogComponent, + DataKeyConfigComponent, + DatasourceComponent, + DatasourcesComponent, + EntityAliasSelectComponent, + FilterSelectComponent, + WidgetSettingsComponent + ] +}) +export class WidgetConfigComponentsModule { } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html index 872969bd15..cde8205f62 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html @@ -147,7 +147,8 @@ + [actionSources]="modelValue.actionSources" + formControlName="actions">
@@ -180,29 +181,21 @@
-
- - -
-
-
widget-config.actions
- - - - {{ widgetAction.icon }} - {{ widgetAction.name }} - - - - - -
-
+
+ +
{{basicModeDirectiveError}}
+ +
+ + + + + + +
+
@@ -239,6 +232,7 @@ modelValue?.isDataEnabled" [formGroup]="dataSettings">
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts index 7a141f6e75..3d9f60f1ad 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts @@ -16,5 +16,100 @@ import { WidgetActionCallbacks } from './action/manage-widget-actions.component.models'; import { DatasourceCallbacks } from '@home/components/widget/datasource.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { Observable } from 'rxjs'; +import { AfterViewInit, Directive, EventEmitter, Inject, OnInit } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { AbstractControl, UntypedFormGroup } from '@angular/forms'; +import { WidgetConfigMode } from '@shared/models/widget.models'; export type WidgetConfigCallbacks = DatasourceCallbacks & WidgetActionCallbacks; + +export interface IBasicWidgetConfigComponent { + + widgetConfig: WidgetConfigComponentData; + widgetConfigChanged: Observable; + validateConfig(): boolean; + +} + +@Directive() +// eslint-disable-next-line @angular-eslint/directive-class-suffix +export abstract class BasicWidgetConfigComponent extends PageComponent implements + IBasicWidgetConfigComponent, OnInit, AfterViewInit { + + basicMode = WidgetConfigMode.basic; + + widgetConfigValue: WidgetConfigComponentData; + + set widgetConfig(value: WidgetConfigComponentData) { + this.widgetConfigValue = value; + this.setupConfig(this.widgetConfigValue); + } + + get widgetConfig(): WidgetConfigComponentData { + return this.widgetConfigValue; + } + + widgetConfigChangedEmitter = new EventEmitter(); + widgetConfigChanged = this.widgetConfigChangedEmitter.asObservable(); + + protected constructor(@Inject(Store) protected store: Store) { + super(store); + } + + ngOnInit() {} + + ngAfterViewInit(): void { + setTimeout(() => { + if (!this.validateConfig()) { + this.onConfigChanged(this.prepareOutputConfig(this.configForm().value)); + } + }, 0); + } + + protected setupConfig(widgetConfig: WidgetConfigComponentData) { + this.onConfigSet(widgetConfig); + this.updateValidators(false); + for (const trigger of this.validatorTriggers()) { + const path = trigger.split('.'); + let control: AbstractControl = this.configForm(); + for (const part of path) { + control = control.get(part); + } + control.valueChanges.subscribe(() => { + this.updateValidators(true, trigger); + }); + } + this.configForm().valueChanges.subscribe((updated: any) => { + this.onConfigChanged(this.prepareOutputConfig(updated)); + }); + } + + protected updateValidators(emitEvent: boolean, trigger?: string) { + } + + protected validatorTriggers(): string[] { + return []; + } + + protected onConfigChanged(widgetConfig: WidgetConfigComponentData) { + this.widgetConfigValue = widgetConfig; + this.widgetConfigChangedEmitter.emit(this.widgetConfigValue); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + return config; + } + + public validateConfig(): boolean { + return this.configForm().valid; + } + + protected abstract configForm(): UntypedFormGroup; + + protected abstract onConfigSet(configData: WidgetConfigComponentData); + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss index 786456dacf..91b3368ad0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.scss @@ -41,6 +41,11 @@ gap: 16px; } } + .tb-basic-mode-directive-error { + font-size: 13px; + font-weight: 400; + color: rgb(221, 44, 0); + } } :host ::ng-deep { diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index 8eafe8855e..f7d1337ba3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -14,7 +14,20 @@ /// limitations under the License. /// -import { ChangeDetectorRef, Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + ComponentFactoryResolver, + ComponentRef, + forwardRef, + Input, + OnChanges, + OnDestroy, + OnInit, + SimpleChanges, + ViewChild, + ViewContainerRef +} from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -26,7 +39,6 @@ import { JsonSchema, JsonSettingsSchema, Widget, - WidgetActionDescriptor, WidgetConfigMode, widgetType } from '@shared/models/widget.models'; @@ -50,7 +62,10 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { TranslateService } from '@ngx-translate/core'; import { EntityType } from '@shared/models/entity-type.models'; import { Observable, of, Subscription } from 'rxjs'; -import { WidgetConfigCallbacks } from '@home/components/widget/widget-config.component.models'; +import { + IBasicWidgetConfigComponent, + WidgetConfigCallbacks +} from '@home/components/widget/widget-config.component.models'; import { EntityAliasDialogComponent, EntityAliasDialogData @@ -59,17 +74,14 @@ import { catchError, mergeMap, tap } from 'rxjs/operators'; import { MatDialog } from '@angular/material/dialog'; import { EntityService } from '@core/http/entity.service'; import { JsonFormComponentData } from '@shared/components/json-form/json-form-component.models'; -import { WidgetActionsData } from './action/manage-widget-actions.component.models'; import { Dashboard } from '@shared/models/dashboard.models'; import { entityFields } from '@shared/models/entity.models'; import { Filter, singleEntityFilterFromDeviceId } from '@shared/models/query/query.models'; import { FilterDialogComponent, FilterDialogData } from '@home/components/filter/filter-dialog.component'; import { ToggleHeaderOption } from '@shared/components/toggle-header.component'; import { coerceBoolean } from '@shared/decorators/coercion'; -import { - ManageWidgetActionsDialogComponent, - ManageWidgetActionsDialogData -} from '@home/components/widget/action/manage-widget-actions-dialog.component'; +import { basicWidgetConfigComponentsMap } from '@home/components/widget/basic-config/basic-widget-config.module'; +import Timeout = NodeJS.Timeout; const emptySettingsSchema: JsonSchema = { type: 'object', @@ -97,7 +109,9 @@ const defaultSettingsForm = [ } ] }) -export class WidgetConfigComponent extends PageComponent implements OnInit, OnDestroy, ControlValueAccessor, Validator { +export class WidgetConfigComponent extends PageComponent implements OnInit, OnDestroy, ControlValueAccessor, Validator, OnChanges { + + @ViewChild('basicModeContainer', {read: ViewContainerRef, static: false}) basicModeContainer: ViewContainerRef; widgetTypes = widgetType; @@ -146,6 +160,8 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe widgetEditMode = this.utils.widgetEditMode; + basicModeDirectiveError: string; + modelValue: WidgetConfigComponentData; private propagateChange = null; @@ -160,6 +176,11 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe public advancedSettings: UntypedFormGroup; public actionsSettings: UntypedFormGroup; + private createBasicModeComponentTimeout: Timeout; + private basicModeComponentRef: ComponentRef; + private basicModeComponent: IBasicWidgetConfigComponent; + private basicModeComponentChangeSubscription: Subscription; + private dataSettingsChangesSubscription: Subscription; private targetDeviceSettingsSubscription: Subscription; private widgetSettingsSubscription: Subscription; @@ -172,6 +193,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private entityService: EntityService, private dialog: MatDialog, public translate: TranslateService, + private cfr: ComponentFactoryResolver, private fb: UntypedFormBuilder, private cd: ChangeDetectorRef) { super(store); @@ -218,11 +240,25 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe desktopHide: [false] }); this.actionsSettings = this.fb.group({ - actionsData: [null, []] + actions: [null, []] }); } + ngOnChanges(changes: SimpleChanges): void { + for (const propName of Object.keys(changes)) { + const change = changes[propName]; + if (!change.firstChange && change.currentValue !== change.previousValue) { + if (propName === 'widgetConfigMode') { + if (this.hasBasicModeDirective) { + this.setupConfig(); + } + } + } + } + } + ngOnDestroy(): void { + this.destroyBasicModeComponent(); this.removeChangeSubscriptions(); } @@ -360,7 +396,61 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe writeValue(value: WidgetConfigComponentData): void { this.modelValue = value; + this.setupConfig(); + } + + private setupConfig() { + this.destroyBasicModeComponent(); this.removeChangeSubscriptions(); + if (this.hasBasicModeDirective && this.widgetConfigMode === WidgetConfigMode.basic) { + this.setupBasicModeConfig(); + } else { + this.setupDefaultConfig(); + } + } + + private setupBasicModeConfig() { + const componentType = basicWidgetConfigComponentsMap[this.modelValue.basicModeDirective]; + if (!componentType) { + this.basicModeDirectiveError = this.translate.instant('widget-config.settings-component-not-found', + {selector: this.modelValue.basicModeDirective}); + } else { + const factory = this.cfr.resolveComponentFactory(componentType); + this.createBasicModeComponentTimeout = setTimeout(() => { + this.createBasicModeComponentTimeout = null; + this.basicModeComponentRef = this.basicModeContainer.createComponent(factory); + this.basicModeComponent = this.basicModeComponentRef.instance; + this.basicModeComponent.widgetConfig = this.modelValue; + this.basicModeComponentChangeSubscription = this.basicModeComponent.widgetConfigChanged.subscribe((data) => { + this.modelValue = data; + this.propagateChange(this.modelValue); + }); + this.cd.markForCheck(); + }, 0); + } + } + + private destroyBasicModeComponent() { + this.basicModeDirectiveError = null; + if (this.basicModeComponentChangeSubscription) { + this.basicModeComponentChangeSubscription.unsubscribe(); + this.basicModeComponentChangeSubscription = null; + } + if (this.createBasicModeComponentTimeout) { + clearTimeout(this.createBasicModeComponentTimeout); + this.createBasicModeComponentTimeout = null; + } + if (this.basicModeComponentRef) { + this.basicModeComponentRef.destroy(); + this.basicModeComponentRef = null; + this.basicModeComponent = null; + } + if (this.basicModeContainer) { + this.basicModeContainer.clear(); + } + } + + private setupDefaultConfig() { if (this.modelValue) { if (this.widgetType !== this.modelValue.widgetType) { this.widgetType = this.modelValue.widgetType; @@ -399,13 +489,9 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe {emitEvent: false} ); this.updateWidgetSettingsEnabledState(); - const actionsData: WidgetActionsData = { - actionsMap: config.actions || {}, - actionSources: this.modelValue.actionSources || {} - }; this.actionsSettings.patchValue( { - actionsData + actions: config.actions || {} }, {emitEvent: false} ); @@ -449,9 +535,9 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } else if (this.widgetType === widgetType.alarm) { this.dataSettings.patchValue( { alarmFilterConfig: isDefined(config.alarmFilterConfig) ? - config.alarmFilterConfig : - { statusList: [AlarmSearchStatus.ACTIVE], searchPropagatedAlarms: true }, - alarmSource: config.alarmSource }, {emitEvent: false} + config.alarmFilterConfig : + { statusList: [AlarmSearchStatus.ACTIVE], searchPropagatedAlarms: true }, + alarmSource: config.alarmSource }, {emitEvent: false} ); } } @@ -590,12 +676,20 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private updateActionSettings() { if (this.modelValue) { if (this.modelValue.config) { - this.modelValue.config.actions = (this.actionsSettings.get('actionsData').value as WidgetActionsData).actionsMap; + this.modelValue.config.actions = this.actionsSettings.get('actions').value; } this.propagateChange(this.modelValue); } } + public get hasBasicModeDirective(): boolean { + return this.modelValue?.basicModeDirective?.length > 0; + } + + public get useDefinedBasicModeDirective(): boolean { + return this.modelValue?.basicModeDirective?.length && !this.basicModeDirectiveError; + } + public get displayAppearance(): boolean { return this.displayAppearanceDataSettings || this.displayAdvancedAppearance; } @@ -631,28 +725,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe return this.widgetType !== widgetType.static && !this.modelValue?.typeParameters?.processNoDataByWidget; } - public get widgetActionSourceIds(): Array { - const actionsData: WidgetActionsData = this.actionsSettings.get('actionsData').value; - return actionsData?.actionsMap ? Object.keys(actionsData.actionsMap) : []; - } - - public widgetActionsByActionSourceId(actionSourceId: string): Array { - const actionsData: WidgetActionsData = this.actionsSettings.get('actionsData').value; - return actionsData?.actionsMap[actionSourceId] || []; - } - - public get hasWidgetActions(): boolean { - const actionsData: WidgetActionsData = this.actionsSettings.get('actionsData').value; - if (actionsData?.actionsMap) { - for (const actionSourceId of Object.keys(actionsData.actionsMap)) { - if (actionsData.actionsMap[actionSourceId] && actionsData.actionsMap[actionSourceId].length) { - return true; - } - } - } - return false; - } - public onlyHistoryTimewindow(): boolean { if (this.widgetType === widgetType.latest) { const datasources = this.dataSettings.get('datasources').value; @@ -662,28 +734,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } } - public manageWidgetActions() { - const actionsData: WidgetActionsData = this.actionsSettings.get('actionsData').value; - this.dialog.open(ManageWidgetActionsDialogComponent, { - disableClose: true, - panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], - data: { - widgetTitle: this.modelValue.widgetName, - callbacks: this.widgetConfigCallbacks, - actionsData: deepClone(actionsData), - widgetType: this.widgetType - } - }).afterClosed().subscribe( - (res) => { - if (res) { - this.actionsSettings.get('actionsData').patchValue(res); - this.cd.markForCheck(); - } - } - ); - } - public generateDataKey(chip: any, type: DataKeyType, datakeySettingsSchema: JsonSettingsSchema): DataKey { if (isObject(chip)) { (chip as DataKey)._hash = Math.random(); @@ -819,7 +869,14 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } public validate(c: UntypedFormControl) { - if (!this.dataSettings.valid) { + if (this.basicModeComponent && + !this.basicModeComponent.validateConfig()) { + return { + basicWidgetConfig: { + valid: false + } + }; + } else if (!this.dataSettings.valid) { return { dataSettings: { valid: false diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index 090d637c99..c00d0a8e82 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -460,6 +460,7 @@ export interface WidgetConfigComponentData { settingsDirective: string; dataKeySettingsDirective: string; latestDataKeySettingsDirective: string; + basicModeDirective: string; } export const MissingWidgetType: WidgetInfo = { 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 81a4aa93c8..fb906561b0 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -5119,6 +5119,7 @@ "markdown-css": "Markdown/HTML CSS" }, "simple-card": { + "label": "Label", "label-position": "Label position", "label-position-left": "Left", "label-position-top": "Top" From 1aa28776340030e7c20c90b5ccf24f9ac15eb8c8 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 30 May 2023 13:47:52 +0300 Subject: [PATCH 098/207] UI: Fix widget config validation in basic mode --- .../components/widget/widget-config.component.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index f7d1337ba3..d42f441c7c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -869,13 +869,14 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } public validate(c: UntypedFormControl) { - if (this.basicModeComponent && - !this.basicModeComponent.validateConfig()) { - return { - basicWidgetConfig: { - valid: false - } - }; + if (this.basicModeComponent) { + if (!this.basicModeComponent.validateConfig()) { + return { + basicWidgetConfig: { + valid: false + } + }; + } } else if (!this.dataSettings.valid) { return { dataSettings: { From 4ae401c54bd02b4638fbc1727d0977de5dfb263e Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 30 May 2023 14:00:41 +0300 Subject: [PATCH 099/207] Monitoring service refactoring (for compatibility with PE integrations monitoring) --- .../ThingsboardMonitoringApplication.java | 26 +++ ...argetConfig.java => MonitoringConfig.java} | 8 +- .../monitoring/config/MonitoringTarget.java | 24 +++ .../CoapTransportMonitoringConfig.java | 3 +- .../config/{ => transport}/DeviceConfig.java | 3 +- .../HttpTransportMonitoringConfig.java | 3 +- .../Lwm2mTransportMonitoringConfig.java | 3 +- .../MqttTransportMonitoringConfig.java | 3 +- .../transport}/TransportInfo.java | 7 +- .../TransportMonitoringConfig.java | 9 +- .../transport/TransportMonitoringTarget.java | 34 +++ .../config/{ => transport}/TransportType.java | 12 +- .../monitoring/data/Latencies.java | 6 +- ...tion.java => ServiceFailureException.java} | 6 +- .../BaseHealthChecker.java} | 74 +++---- .../service/BaseMonitoringService.java | 101 +++++++++ .../service/MonitoringReporter.java | 10 +- .../transport/TransportHealthChecker.java | 139 ++++++++++++ .../TransportsMonitoringService.java | 41 ++++ .../impl/CoapTransportHealthChecker.java | 12 +- .../impl/HttpTransportHealthChecker.java | 12 +- .../impl/Lwm2mTransportHealthChecker.java | 12 +- .../impl/MqttTransportHealthChecker.java | 12 +- .../transport/TransportMonitoringService.java | 198 ------------------ .../main/resources/lwm2m/device_profile.json | 1 - .../src/main/resources/tb-monitoring.yml | 51 ++--- 26 files changed, 471 insertions(+), 339 deletions(-) rename monitoring/src/main/java/org/thingsboard/monitoring/config/{MonitoringTargetConfig.java => MonitoringConfig.java} (84%) create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTarget.java rename monitoring/src/main/java/org/thingsboard/monitoring/config/{service => transport}/CoapTransportMonitoringConfig.java (91%) rename monitoring/src/main/java/org/thingsboard/monitoring/config/{ => transport}/DeviceConfig.java (92%) rename monitoring/src/main/java/org/thingsboard/monitoring/config/{service => transport}/HttpTransportMonitoringConfig.java (91%) rename monitoring/src/main/java/org/thingsboard/monitoring/config/{service => transport}/Lwm2mTransportMonitoringConfig.java (91%) rename monitoring/src/main/java/org/thingsboard/monitoring/config/{service => transport}/MqttTransportMonitoringConfig.java (92%) rename monitoring/src/main/java/org/thingsboard/monitoring/{data => config/transport}/TransportInfo.java (80%) rename monitoring/src/main/java/org/thingsboard/monitoring/config/{service => transport}/TransportMonitoringConfig.java (73%) create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java rename monitoring/src/main/java/org/thingsboard/monitoring/config/{ => transport}/TransportType.java (67%) rename monitoring/src/main/java/org/thingsboard/monitoring/data/{TransportFailureException.java => ServiceFailureException.java} (80%) rename monitoring/src/main/java/org/thingsboard/monitoring/{transport/TransportHealthChecker.java => service/BaseHealthChecker.java} (54%) create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/service/BaseMonitoringService.java create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportHealthChecker.java create mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportsMonitoringService.java rename monitoring/src/main/java/org/thingsboard/monitoring/{ => service}/transport/impl/CoapTransportHealthChecker.java (86%) rename monitoring/src/main/java/org/thingsboard/monitoring/{ => service}/transport/impl/HttpTransportHealthChecker.java (84%) rename monitoring/src/main/java/org/thingsboard/monitoring/{ => service}/transport/impl/Lwm2mTransportHealthChecker.java (84%) rename monitoring/src/main/java/org/thingsboard/monitoring/{ => service}/transport/impl/MqttTransportHealthChecker.java (88%) delete mode 100644 monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportMonitoringService.java diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/ThingsboardMonitoringApplication.java b/monitoring/src/main/java/org/thingsboard/monitoring/ThingsboardMonitoringApplication.java index 2daf5c5b7b..399d0f4a56 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/ThingsboardMonitoringApplication.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/ThingsboardMonitoringApplication.java @@ -16,21 +16,47 @@ package org.thingsboard.monitoring; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.EnableScheduling; +import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.monitoring.service.BaseMonitoringService; +import java.util.List; import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; @SpringBootApplication @EnableScheduling @Slf4j public class ThingsboardMonitoringApplication { + @Autowired + private List> monitoringServices; + + @Value("${monitoring.monitoring_rate_ms}") + private int monitoringRateMs; + public static void main(String[] args) { new SpringApplicationBuilder(ThingsboardMonitoringApplication.class) .properties(Map.of("spring.config.name", "tb-monitoring")) .run(args); } + @EventListener(ApplicationReadyEvent.class) + public void startMonitoring() { + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("monitoring-executor")); + scheduler.scheduleWithFixedDelay(() -> { + monitoringServices.forEach(monitoringService -> { + monitoringService.runChecks(); + }); + }, 0, monitoringRateMs, TimeUnit.MILLISECONDS); + } + } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTargetConfig.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringConfig.java similarity index 84% rename from monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTargetConfig.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringConfig.java index 5f1ab49e91..4304ecdf0e 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTargetConfig.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringConfig.java @@ -15,12 +15,10 @@ */ package org.thingsboard.monitoring.config; -import lombok.Data; +import java.util.List; -@Data -public class MonitoringTargetConfig { +public interface MonitoringConfig { - private String baseUrl; - private DeviceConfig device; + List getTargets(); } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTarget.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTarget.java new file mode 100644 index 0000000000..0e62670f81 --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/MonitoringTarget.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.config; + +import java.util.UUID; + +public interface MonitoringTarget { + + UUID getDeviceId(); + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/CoapTransportMonitoringConfig.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/CoapTransportMonitoringConfig.java similarity index 91% rename from monitoring/src/main/java/org/thingsboard/monitoring/config/service/CoapTransportMonitoringConfig.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/transport/CoapTransportMonitoringConfig.java index 905858b4eb..a95aca18f4 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/CoapTransportMonitoringConfig.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/CoapTransportMonitoringConfig.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.config.service; +package org.thingsboard.monitoring.config.transport; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; -import org.thingsboard.monitoring.config.TransportType; @Component @ConditionalOnProperty(name = "monitoring.transports.coap.enabled", havingValue = "true") diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/DeviceConfig.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/DeviceConfig.java similarity index 92% rename from monitoring/src/main/java/org/thingsboard/monitoring/config/DeviceConfig.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/transport/DeviceConfig.java index 548ad6d08b..94c0ea3a84 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/DeviceConfig.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/DeviceConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.config; +package org.thingsboard.monitoring.config.transport; import lombok.Data; import org.apache.commons.lang3.StringUtils; @@ -25,6 +25,7 @@ import java.util.UUID; public class DeviceConfig { private UUID id; + private String name; private DeviceCredentials credentials; public void setId(String id) { diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/HttpTransportMonitoringConfig.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/HttpTransportMonitoringConfig.java similarity index 91% rename from monitoring/src/main/java/org/thingsboard/monitoring/config/service/HttpTransportMonitoringConfig.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/transport/HttpTransportMonitoringConfig.java index 3a3e8f612c..3b2be2343d 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/HttpTransportMonitoringConfig.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/HttpTransportMonitoringConfig.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.config.service; +package org.thingsboard.monitoring.config.transport; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; -import org.thingsboard.monitoring.config.TransportType; @Component @ConditionalOnProperty(name = "monitoring.transports.http.enabled", havingValue = "true") diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/Lwm2mTransportMonitoringConfig.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/Lwm2mTransportMonitoringConfig.java similarity index 91% rename from monitoring/src/main/java/org/thingsboard/monitoring/config/service/Lwm2mTransportMonitoringConfig.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/transport/Lwm2mTransportMonitoringConfig.java index 4d97de8366..7d375abd6e 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/Lwm2mTransportMonitoringConfig.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/Lwm2mTransportMonitoringConfig.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.config.service; +package org.thingsboard.monitoring.config.transport; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; -import org.thingsboard.monitoring.config.TransportType; @Component @ConditionalOnProperty(name = "monitoring.transports.lwm2m.enabled", havingValue = "true") diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/MqttTransportMonitoringConfig.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/MqttTransportMonitoringConfig.java similarity index 92% rename from monitoring/src/main/java/org/thingsboard/monitoring/config/service/MqttTransportMonitoringConfig.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/transport/MqttTransportMonitoringConfig.java index 7fef5b95dc..ebc91a327e 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/MqttTransportMonitoringConfig.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/MqttTransportMonitoringConfig.java @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.config.service; +package org.thingsboard.monitoring.config.transport; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; -import org.thingsboard.monitoring.config.TransportType; @Component @ConditionalOnProperty(name = "monitoring.transports.mqtt.enabled", havingValue = "true") diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/TransportInfo.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java similarity index 80% rename from monitoring/src/main/java/org/thingsboard/monitoring/data/TransportInfo.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java index d7619ea32d..6fb2e25ec9 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/TransportInfo.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportInfo.java @@ -13,20 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.data; +package org.thingsboard.monitoring.config.transport; import lombok.Data; -import org.thingsboard.monitoring.config.TransportType; @Data public class TransportInfo { private final TransportType transportType; - private final String url; + private final String baseUrl; @Override public String toString() { - return String.format("%s (%s)", transportType, url); + return String.format("%s transport (%s)", transportType, baseUrl); } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/TransportMonitoringConfig.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringConfig.java similarity index 73% rename from monitoring/src/main/java/org/thingsboard/monitoring/config/service/TransportMonitoringConfig.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringConfig.java index 0712d1d919..77d702f779 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/service/TransportMonitoringConfig.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringConfig.java @@ -13,20 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.config.service; +package org.thingsboard.monitoring.config.transport; import lombok.Data; -import org.thingsboard.monitoring.config.MonitoringTargetConfig; -import org.thingsboard.monitoring.config.TransportType; +import org.thingsboard.monitoring.config.MonitoringConfig; import java.util.List; @Data -public abstract class TransportMonitoringConfig { +public abstract class TransportMonitoringConfig implements MonitoringConfig { private int requestTimeoutMs; - private List targets; + private List targets; public abstract TransportType getTransportType(); diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java new file mode 100644 index 0000000000..816f64fbce --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportMonitoringTarget.java @@ -0,0 +1,34 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.config.transport; + +import lombok.Data; +import org.thingsboard.monitoring.config.MonitoringTarget; + +import java.util.UUID; + +@Data +public class TransportMonitoringTarget implements MonitoringTarget { + + private String baseUrl; + private DeviceConfig device; // set manually during initialization + + @Override + public UUID getDeviceId() { + return device.getId(); + } + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/config/TransportType.java b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportType.java similarity index 67% rename from monitoring/src/main/java/org/thingsboard/monitoring/config/TransportType.java rename to monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportType.java index a3aaa7ec98..eeb085348b 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/config/TransportType.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/config/transport/TransportType.java @@ -13,15 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.config; +package org.thingsboard.monitoring.config.transport; import lombok.AllArgsConstructor; import lombok.Getter; -import org.thingsboard.monitoring.transport.TransportHealthChecker; -import org.thingsboard.monitoring.transport.impl.CoapTransportHealthChecker; -import org.thingsboard.monitoring.transport.impl.HttpTransportHealthChecker; -import org.thingsboard.monitoring.transport.impl.Lwm2mTransportHealthChecker; -import org.thingsboard.monitoring.transport.impl.MqttTransportHealthChecker; +import org.thingsboard.monitoring.service.transport.TransportHealthChecker; +import org.thingsboard.monitoring.service.transport.impl.CoapTransportHealthChecker; +import org.thingsboard.monitoring.service.transport.impl.HttpTransportHealthChecker; +import org.thingsboard.monitoring.service.transport.impl.Lwm2mTransportHealthChecker; +import org.thingsboard.monitoring.service.transport.impl.MqttTransportHealthChecker; @AllArgsConstructor @Getter diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/Latencies.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/Latencies.java index 8141c34586..3370d42462 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/Latencies.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/Latencies.java @@ -15,16 +15,14 @@ */ package org.thingsboard.monitoring.data; -import org.thingsboard.monitoring.config.TransportType; - public class Latencies { public static final String WS_UPDATE = "wsUpdate"; public static final String WS_CONNECT = "wsConnect"; public static final String LOG_IN = "logIn"; - public static String transportRequest(TransportType transportType) { - return String.format("%sTransportRequest", transportType.name().toLowerCase()); + public static String request(String key) { + return String.format("%sRequest", key); } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/data/TransportFailureException.java b/monitoring/src/main/java/org/thingsboard/monitoring/data/ServiceFailureException.java similarity index 80% rename from monitoring/src/main/java/org/thingsboard/monitoring/data/TransportFailureException.java rename to monitoring/src/main/java/org/thingsboard/monitoring/data/ServiceFailureException.java index 8157c4af5f..dc91a56a3c 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/data/TransportFailureException.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/data/ServiceFailureException.java @@ -15,13 +15,13 @@ */ package org.thingsboard.monitoring.data; -public class TransportFailureException extends RuntimeException { +public class ServiceFailureException extends RuntimeException { - public TransportFailureException(Throwable cause) { + public ServiceFailureException(Throwable cause) { super(cause.getMessage(), cause); } - public TransportFailureException(String message) { + public ServiceFailureException(String message) { super(message); } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportHealthChecker.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseHealthChecker.java similarity index 54% rename from monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportHealthChecker.java rename to monitoring/src/main/java/org/thingsboard/monitoring/service/BaseHealthChecker.java index 0c742e7709..affca1ce09 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportHealthChecker.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/BaseHealthChecker.java @@ -13,34 +13,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.transport; +package org.thingsboard.monitoring.service; -import com.fasterxml.jackson.databind.node.TextNode; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.monitoring.client.TbClient; import org.thingsboard.monitoring.client.WsClient; -import org.thingsboard.monitoring.config.MonitoringTargetConfig; -import org.thingsboard.monitoring.config.TransportType; -import org.thingsboard.monitoring.config.service.TransportMonitoringConfig; +import org.thingsboard.monitoring.config.MonitoringConfig; +import org.thingsboard.monitoring.config.MonitoringTarget; import org.thingsboard.monitoring.data.Latencies; import org.thingsboard.monitoring.data.MonitoredServiceKey; -import org.thingsboard.monitoring.data.TransportFailureException; -import org.thingsboard.monitoring.data.TransportInfo; -import org.thingsboard.monitoring.service.MonitoringReporter; +import org.thingsboard.monitoring.data.ServiceFailureException; import org.thingsboard.monitoring.util.TbStopWatch; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.UUID; +@RequiredArgsConstructor @Slf4j -public abstract class TransportHealthChecker { +public abstract class BaseHealthChecker { protected final C config; - protected final MonitoringTargetConfig target; - private TransportInfo transportInfo; + protected final T target; + + private Object info; @Autowired private MonitoringReporter reporter; @@ -51,73 +50,66 @@ public abstract class TransportHealthChecker, T extends MonitoringTarget> { + + @Autowired + private List configs; + private final List> healthCheckers = new LinkedList<>(); + private final List devices = new LinkedList<>(); + + @Autowired + private TbClient tbClient; + @Autowired + private WsClientFactory wsClientFactory; + @Autowired + private TbStopWatch stopWatch; + @Autowired + private MonitoringReporter reporter; + @Autowired + protected ApplicationContext applicationContext; + + @PostConstruct + private void init() { + tbClient.logIn(); + configs.forEach(config -> { + config.getTargets().forEach(target -> { + BaseHealthChecker healthChecker = (BaseHealthChecker) createHealthChecker(config, target); + log.info("Initializing {}", healthChecker.getClass().getSimpleName()); + healthChecker.initialize(tbClient); + devices.add(target.getDeviceId()); + healthCheckers.add(healthChecker); + }); + }); + } + + public final void runChecks() { + if (healthCheckers.isEmpty()) { + return; + } + try { + log.info("Starting {}", getName()); + stopWatch.start(); + String accessToken = tbClient.logIn(); + reporter.reportLatency(Latencies.LOG_IN, stopWatch.getTime()); + + try (WsClient wsClient = wsClientFactory.createClient(accessToken)) { + wsClient.subscribeForTelemetry(devices, TransportHealthChecker.TEST_TELEMETRY_KEY).waitForReply(); + + for (BaseHealthChecker healthChecker : healthCheckers) { + healthChecker.check(wsClient); + } + } + reporter.reportLatencies(tbClient); + log.debug("Finished {}", getName()); + } catch (Throwable error) { + try { + reporter.serviceFailure(MonitoredServiceKey.GENERAL, error); + } catch (Throwable reportError) { + log.error("Error occurred during service failure reporting", reportError); + } + } + } + + protected abstract BaseHealthChecker createHealthChecker(C config, T target); + + protected abstract String getName(); + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringReporter.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringReporter.java index 4649e31ac4..f41454a76a 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringReporter.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringReporter.java @@ -52,8 +52,8 @@ public class MonitoringReporter { @Value("${monitoring.failures_threshold}") private int failuresThreshold; - @Value("${monitoring.send_repeated_failure_notification}") - private boolean sendRepeatedFailureNotification; + @Value("${monitoring.repeated_failure_notification}") + private int repeatedFailureNotification; @Value("${monitoring.latency.enabled}") private boolean latencyReportingEnabled; @@ -75,7 +75,7 @@ public class MonitoringReporter { return; } log.info("Latencies:\n{}", latencies.stream().map(latency -> latency.getKey() + ": " + latency.getAvg() + " ms") - .collect(Collectors.joining("\n"))); + .collect(Collectors.joining("\n")) + "\n"); if (!latencyReportingEnabled) return; @@ -86,7 +86,7 @@ public class MonitoringReporter { try { if (StringUtils.isBlank(reportingAssetId)) { - String assetName = "Monitoring"; + String assetName = "[Monitoring] Latencies"; Asset monitoringAsset = tbClient.findAsset(assetName).orElseGet(() -> { Asset asset = new Asset(); asset.setType("Monitoring"); @@ -122,7 +122,7 @@ public class MonitoringReporter { int failuresCount = failuresCounters.computeIfAbsent(serviceKey, k -> new AtomicInteger()).incrementAndGet(); ServiceFailureNotification notification = new ServiceFailureNotification(serviceKey, error, failuresCount); log.error(notification.getText()); - if (failuresCount == failuresThreshold || (sendRepeatedFailureNotification && failuresCount % failuresThreshold == 0)) { + if (failuresCount == failuresThreshold || (repeatedFailureNotification != 0 && failuresCount % repeatedFailureNotification == 0)) { notificationService.sendNotification(notification); } } diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportHealthChecker.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportHealthChecker.java new file mode 100644 index 0000000000..c822720f23 --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportHealthChecker.java @@ -0,0 +1,139 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.service.transport; + +import com.fasterxml.jackson.databind.node.TextNode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.RandomStringUtils; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.monitoring.client.TbClient; +import org.thingsboard.monitoring.config.transport.DeviceConfig; +import org.thingsboard.monitoring.config.transport.TransportInfo; +import org.thingsboard.monitoring.config.transport.TransportMonitoringConfig; +import org.thingsboard.monitoring.config.transport.TransportMonitoringTarget; +import org.thingsboard.monitoring.config.transport.TransportType; +import org.thingsboard.monitoring.service.BaseHealthChecker; +import org.thingsboard.monitoring.util.ResourceUtils; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.TbResource; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredentials; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; +import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecBootstrapClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredential; +import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; +import org.thingsboard.server.common.data.device.data.DefaultDeviceTransportConfiguration; +import org.thingsboard.server.common.data.device.data.DeviceData; +import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.common.data.security.DeviceCredentialsType; + +@Slf4j +public abstract class TransportHealthChecker extends BaseHealthChecker { + + private static final String DEFAULT_DEVICE_NAME = "[Monitoring] %s transport (%s)"; + private static final String DEFAULT_PROFILE_NAME = "[Monitoring] %s"; + + public TransportHealthChecker(C config, TransportMonitoringTarget target) { + super(config, target); + } + + @Override + protected void initialize(TbClient tbClient) { + String deviceName = String.format(DEFAULT_DEVICE_NAME, config.getTransportType(), target.getBaseUrl()); + Device device = tbClient.getTenantDevice(deviceName) + .orElseGet(() -> { + log.info("Creating new device '{}'", deviceName); + return createDevice(config.getTransportType(), deviceName, tbClient); + }); + DeviceCredentials credentials = tbClient.getDeviceCredentialsByDeviceId(device.getId()) + .orElseThrow(() -> new IllegalArgumentException("No credentials found for device " + device.getId())); + + DeviceConfig deviceConfig = new DeviceConfig(); + deviceConfig.setId(device.getId().toString()); + deviceConfig.setName(deviceName); + deviceConfig.setCredentials(credentials); + target.setDevice(deviceConfig); + } + + @Override + protected String createTestPayload(String testValue) { + return JacksonUtil.newObjectNode().set(TEST_TELEMETRY_KEY, new TextNode(testValue)).toString(); + } + + @Override + protected Object getInfo() { + return new TransportInfo(getTransportType(), target.getBaseUrl()); + } + + @Override + protected String getKey() { + return getTransportType().name().toLowerCase() + "Transport"; + } + + protected abstract TransportType getTransportType(); + + + private Device createDevice(TransportType transportType, String name, TbClient tbClient) { + Device device = new Device(); + device.setName(name); + + DeviceCredentials credentials = new DeviceCredentials(); + credentials.setCredentialsId(RandomStringUtils.randomAlphabetic(20)); + + DeviceData deviceData = new DeviceData(); + deviceData.setConfiguration(new DefaultDeviceConfiguration()); + if (transportType != TransportType.LWM2M) { + device.setType("default"); + deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration()); + credentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); + } else { + tbClient.getResources(new PageLink(1, 0, "lwm2m monitoring")).getData() + .stream().findFirst() + .orElseGet(() -> { + TbResource newResource = ResourceUtils.getResource("lwm2m/resource.json", TbResource.class); + log.info("Creating LwM2M resource"); + return tbClient.saveResource(newResource); + }); + String profileName = String.format(DEFAULT_PROFILE_NAME, transportType); + DeviceProfile profile = tbClient.getDeviceProfiles(new PageLink(1, 0, profileName)).getData() + .stream().findFirst() + .orElseGet(() -> { + DeviceProfile newProfile = ResourceUtils.getResource("lwm2m/device_profile.json", DeviceProfile.class); + newProfile.setName(profileName); + log.info("Creating LwM2M device profile"); + return tbClient.saveDeviceProfile(newProfile); + }); + device.setType(profileName); + device.setDeviceProfileId(profile.getId()); + deviceData.setTransportConfiguration(new Lwm2mDeviceTransportConfiguration()); + + credentials.setCredentialsType(DeviceCredentialsType.LWM2M_CREDENTIALS); + LwM2MDeviceCredentials lwm2mCreds = new LwM2MDeviceCredentials(); + NoSecClientCredential client = new NoSecClientCredential(); + client.setEndpoint(credentials.getCredentialsId()); + lwm2mCreds.setClient(client); + LwM2MBootstrapClientCredentials bootstrap = new LwM2MBootstrapClientCredentials(); + bootstrap.setBootstrapServer(new NoSecBootstrapClientCredential()); + bootstrap.setLwm2mServer(new NoSecBootstrapClientCredential()); + lwm2mCreds.setBootstrap(bootstrap); + credentials.setCredentialsValue(JacksonUtil.toString(lwm2mCreds)); + } + return tbClient.saveDeviceWithCredentials(device, credentials).get(); + } + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportsMonitoringService.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportsMonitoringService.java new file mode 100644 index 0000000000..b3ce86e799 --- /dev/null +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/TransportsMonitoringService.java @@ -0,0 +1,41 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.monitoring.service.transport; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.thingsboard.monitoring.config.transport.TransportMonitoringConfig; +import org.thingsboard.monitoring.config.transport.TransportMonitoringTarget; +import org.thingsboard.monitoring.service.BaseHealthChecker; +import org.thingsboard.monitoring.service.BaseMonitoringService; + +@Service +@RequiredArgsConstructor +@Slf4j +public final class TransportsMonitoringService extends BaseMonitoringService { + + @Override + protected BaseHealthChecker createHealthChecker(TransportMonitoringConfig config, TransportMonitoringTarget target) { + return applicationContext.getBean(config.getTransportType().getServiceClass(), config, target); + } + + @Override + protected String getName() { + return "transports check"; + } + +} diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/transport/impl/CoapTransportHealthChecker.java b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/impl/CoapTransportHealthChecker.java similarity index 86% rename from monitoring/src/main/java/org/thingsboard/monitoring/transport/impl/CoapTransportHealthChecker.java rename to monitoring/src/main/java/org/thingsboard/monitoring/service/transport/impl/CoapTransportHealthChecker.java index 3e36e62c58..f56415fa6a 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/transport/impl/CoapTransportHealthChecker.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/service/transport/impl/CoapTransportHealthChecker.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.monitoring.transport.impl; +package org.thingsboard.monitoring.service.transport.impl; import lombok.extern.slf4j.Slf4j; import org.eclipse.californium.core.CoapClient; @@ -23,10 +23,10 @@ import org.eclipse.californium.core.coap.MediaTypeRegistry; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import org.thingsboard.monitoring.config.MonitoringTargetConfig; -import org.thingsboard.monitoring.config.TransportType; -import org.thingsboard.monitoring.config.service.CoapTransportMonitoringConfig; -import org.thingsboard.monitoring.transport.TransportHealthChecker; +import org.thingsboard.monitoring.config.transport.CoapTransportMonitoringConfig; +import org.thingsboard.monitoring.config.transport.TransportMonitoringTarget; +import org.thingsboard.monitoring.config.transport.TransportType; +import org.thingsboard.monitoring.service.transport.TransportHealthChecker; import java.io.IOException; @@ -37,7 +37,7 @@ public class CoapTransportHealthChecker extends TransportHealthChecker configs; - private final List> transportHealthCheckers = new LinkedList<>(); - private final List devices = new LinkedList<>(); - - private final TbClient tbClient; - private final WsClientFactory wsClientFactory; - private final TbStopWatch stopWatch; - private final MonitoringReporter reporter; - private final ApplicationContext applicationContext; - private ScheduledExecutorService scheduler; - @Value("${monitoring.transports.monitoring_rate_ms}") - private int monitoringRateMs; - - @PostConstruct - private void init() { - configs.forEach(config -> { - config.getTargets().stream() - .filter(target -> StringUtils.isNotBlank(target.getBaseUrl())) - .peek(target -> checkMonitoringTarget(config, target, tbClient)) - .forEach(target -> { - TransportHealthChecker transportHealthChecker = applicationContext.getBean(config.getTransportType().getServiceClass(), config, target); - transportHealthCheckers.add(transportHealthChecker); - devices.add(target.getDevice().getId()); - }); - }); - scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName("monitoring-executor")); - } - - @EventListener(ApplicationReadyEvent.class) - public void startMonitoring() { - scheduler.scheduleWithFixedDelay(() -> { - try { - log.debug("Starting transports check"); - stopWatch.start(); - String accessToken = tbClient.logIn(); - reporter.reportLatency(Latencies.LOG_IN, stopWatch.getTime()); - - try (WsClient wsClient = wsClientFactory.createClient(accessToken)) { - wsClient.subscribeForTelemetry(devices, TransportHealthChecker.TEST_TELEMETRY_KEY).waitForReply(); - - for (TransportHealthChecker transportHealthChecker : transportHealthCheckers) { - transportHealthChecker.check(wsClient); - } - } - reporter.reportLatencies(tbClient); - log.debug("Finished transports check"); - } catch (Throwable error) { - try { - reporter.serviceFailure(MonitoredServiceKey.GENERAL, error); - } catch (Throwable reportError) { - log.error("Error occurred during service failure reporting", reportError); - } - } - }, 0, monitoringRateMs, TimeUnit.MILLISECONDS); - } - - private void checkMonitoringTarget(TransportMonitoringConfig config, MonitoringTargetConfig target, TbClient tbClient) { - DeviceConfig deviceConfig = target.getDevice(); - tbClient.logIn(); - - DeviceId deviceId; - if (deviceConfig == null || deviceConfig.getId() == null) { - String deviceName = String.format("[%s] Monitoring device (%s)", config.getTransportType(), target.getBaseUrl()); - Device device = tbClient.getTenantDevice(deviceName) - .orElseGet(() -> { - log.info("Creating new device '{}'", deviceName); - return createDevice(config.getTransportType(), deviceName, tbClient); - }); - deviceId = device.getId(); - target.getDevice().setId(deviceId.toString()); - } else { - deviceId = new DeviceId(deviceConfig.getId()); - } - - log.info("Using device {} for {} monitoring", deviceId, config.getTransportType()); - DeviceCredentials credentials = tbClient.getDeviceCredentialsByDeviceId(deviceId) - .orElseThrow(() -> new IllegalArgumentException("No credentials found for device " + deviceId)); - target.getDevice().setCredentials(credentials); - } - - private Device createDevice(TransportType transportType, String name, TbClient tbClient) { - Device device = new Device(); - device.setName(name); - - DeviceCredentials credentials = new DeviceCredentials(); - credentials.setCredentialsId(RandomStringUtils.randomAlphabetic(20)); - - DeviceData deviceData = new DeviceData(); - deviceData.setConfiguration(new DefaultDeviceConfiguration()); - if (transportType != TransportType.LWM2M) { - device.setType("default"); - deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration()); - credentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); - } else { - tbClient.getResources(new PageLink(1, 0, "lwm2m monitoring")).getData() - .stream().findFirst() - .orElseGet(() -> { - TbResource newResource = ResourceUtils.getResource("lwm2m/resource.json", TbResource.class); - log.info("Creating LwM2M resource"); - return tbClient.saveResource(newResource); - }); - String profileName = "LwM2M Monitoring"; - DeviceProfile profile = tbClient.getDeviceProfiles(new PageLink(1, 0, profileName)).getData() - .stream().findFirst() - .orElseGet(() -> { - DeviceProfile newProfile = ResourceUtils.getResource("lwm2m/device_profile.json", DeviceProfile.class); - newProfile.setName(profileName); - log.info("Creating LwM2M device profile"); - return tbClient.saveDeviceProfile(newProfile); - }); - device.setType(profileName); - device.setDeviceProfileId(profile.getId()); - deviceData.setTransportConfiguration(new Lwm2mDeviceTransportConfiguration()); - - credentials.setCredentialsType(DeviceCredentialsType.LWM2M_CREDENTIALS); - LwM2MDeviceCredentials lwm2mCreds = new LwM2MDeviceCredentials(); - NoSecClientCredential client = new NoSecClientCredential(); - client.setEndpoint(credentials.getCredentialsId()); - lwm2mCreds.setClient(client); - LwM2MBootstrapClientCredentials bootstrap = new LwM2MBootstrapClientCredentials(); - bootstrap.setBootstrapServer(new NoSecBootstrapClientCredential()); - bootstrap.setLwm2mServer(new NoSecBootstrapClientCredential()); - lwm2mCreds.setBootstrap(bootstrap); - credentials.setCredentialsValue(JacksonUtil.toString(lwm2mCreds)); - } - return tbClient.saveDeviceWithCredentials(device, credentials).get(); - } - -} diff --git a/monitoring/src/main/resources/lwm2m/device_profile.json b/monitoring/src/main/resources/lwm2m/device_profile.json index 7f93a7e6b6..095f4859e9 100644 --- a/monitoring/src/main/resources/lwm2m/device_profile.json +++ b/monitoring/src/main/resources/lwm2m/device_profile.json @@ -1,5 +1,4 @@ { - "name": "LwM2M Monitoring", "type": "DEFAULT", "image": null, "defaultQueueName": null, diff --git a/monitoring/src/main/resources/tb-monitoring.yml b/monitoring/src/main/resources/tb-monitoring.yml index d89886cd72..88979bff1a 100644 --- a/monitoring/src/main/resources/tb-monitoring.yml +++ b/monitoring/src/main/resources/tb-monitoring.yml @@ -32,79 +32,62 @@ monitoring: # WebSocket request timeout request_timeout_ms: '${WS_REQUEST_TIMEOUT_MS:3000}' + # Checks frequency in milliseconds + monitoring_rate_ms: '${MONITORING_RATE_MS:10000}' # Maximum time between request to transport and WebSocket update check_timeout_ms: '${CHECK_TIMEOUT_MS:5000}' # Failures threshold for notifying failures_threshold: '${FAILURES_THRESHOLD:2}' - # Whether to notify about next failures after first notification (will notify after each FAILURES_THRESHOLD failures) - send_repeated_failure_notification: '${SEND_REPEATED_FAILURE_NOTIFICATION:true}' + # Notify after each REPEATED_FAILURE_NOTIFICATION subsequent failures, 0 to notify only once on first failure + repeated_failure_notification: '${REPEATED_FAILURE_NOTIFICATION:4}' transports: - # Transports check frequency in milliseconds - monitoring_rate_ms: '${TRANSPORTS_MONITORING_RATE_MS:10000}' - mqtt: - # Enable MQTT checks + # Enable MQTT transport checks enabled: '${MQTT_TRANSPORT_MONITORING_ENABLED:true}' # MQTT request timeout in milliseconds request_timeout_ms: '${MQTT_REQUEST_TIMEOUT_MS:4000}' # MQTT QoS qos: '${MQTT_QOS_LEVEL:1}' targets: - # MQTT base url, tcp://DOMAIN:1883 by default + # MQTT transport base url, tcp://DOMAIN:1883 by default - base_url: '${MQTT_TRANSPORT_BASE_URL:tcp://${monitoring.domain}:1883}' - device: - # MQTT device to push telemetry for. If not set - device will be found or created automatically - id: '${MQTT_TRANSPORT_TARGET_DEVICE_ID:}' # To add more targets, use following environment variables: - # monitoring.transports.mqtt.targets[1].base_url, monitoring.transports.mqtt.targets[1].device.id, - # monitoring.transports.mqtt.targets[2].base_url, monitoring.transports.mqtt.targets[2].device.id, etc. + # monitoring.transports.mqtt.targets[1].base_url, monitoring.transports.mqtt.targets[2].base_url, etc. coap: - # Enable CoAP checks + # Enable CoAP transport checks enabled: '${COAP_TRANSPORT_MONITORING_ENABLED:true}' # CoAP request timeout in milliseconds request_timeout_ms: '${COAP_REQUEST_TIMEOUT_MS:4000}' targets: - # CoAP base url, coap://DOMAIN by default + # CoAP transport base url, coap://DOMAIN by default - base_url: '${COAP_TRANSPORT_BASE_URL:coap://${monitoring.domain}}' - # CoAP device to push telemetry for. If not set - device will be found or created automatically - device: - id: '${COAP_TRANSPORT_TARGET_DEVICE_ID:}' # To add more targets, use following environment variables: - # monitoring.transports.coap.targets[1].base_url, monitoring.transports.coap.targets[1].device.id, - # monitoring.transports.coap.targets[2].base_url, monitoring.transports.coap.targets[2].device.id, etc. + # monitoring.transports.coap.targets[1].base_url, monitoring.transports.coap.targets[2].base_url, etc. http: - # Enable HTTP checks + # Enable HTTP transport checks enabled: '${HTTP_TRANSPORT_MONITORING_ENABLED:true}' # HTTP request timeout in milliseconds request_timeout_ms: '${HTTP_REQUEST_TIMEOUT_MS:4000}' targets: - # HTTP base url, https://DOMAIN by default - - base_url: '${HTTP_TRANSPORT_BASE_URL:https://${monitoring.domain}}' - device: - # HTTP device to push telemetry for. If not set - device will be found or created automatically - id: '${HTTP_TRANSPORT_TARGET_DEVICE_ID:}' + # HTTP transport base url, http://DOMAIN by default + - base_url: '${HTTP_TRANSPORT_BASE_URL:http://${monitoring.domain}}' # To add more targets, use following environment variables: - # monitoring.transports.http.targets[1].base_url, monitoring.transports.http.targets[1].device.id, - # monitoring.transports.http.targets[2].base_url, monitoring.transports.http.targets[2].device.id, etc. + # monitoring.transports.http.targets[1].base_url, monitoring.transports.http.targets[2].base_url, etc. lwm2m: - # Enable LwM2M checks + # Enable LwM2M transport checks enabled: '${LWM2M_TRANSPORT_MONITORING_ENABLED:true}' # LwM2M request timeout in milliseconds request_timeout_ms: '${LWM2M_REQUEST_TIMEOUT_MS:4000}' targets: - # LwM2M base url, coap://DOMAIN:5685 by default + # LwM2M transport base url, coap://DOMAIN:5685 by default - base_url: '${LWM2M_TRANSPORT_BASE_URL:coap://${monitoring.domain}:5685}' - # LwM2M device to push telemetry for. If not set - device will be found or created automatically - device: - id: '${LWM2M_TRANSPORT_TARGET_DEVICE_ID:}' # To add more targets, use following environment variables: - # monitoring.transports.lwm2m.targets[1].base_url, monitoring.transports.lwm2m.targets[1].device.id, - # monitoring.transports.lwm2m.targets[2].base_url, monitoring.transports.lwm2m.targets[2].device.id, etc. + # monitoring.transports.lwm2m.targets[1].base_url, monitoring.transports.lwm2m.targets[2].base_url, etc. notification_channels: slack: From 12222808ab715bbbc0c74159731e6e57f78b7fb2 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 30 May 2023 15:11:38 +0300 Subject: [PATCH 100/207] update see examples docs for customer attributes node --- .../common_node_fields_templatization.md | 8 ++-- ...r_attributes_node_fields_templatization.md | 36 +++++++++--------- .../examples/customer-attributes-ft.png | Bin 0 -> 85413 bytes 3 files changed, 22 insertions(+), 22 deletions(-) create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/customer-attributes-ft.png diff --git a/ui-ngx/src/assets/help/en_US/rulenode/common_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/common_node_fields_templatization.md index b32367ed52..dc1e721bd0 100644 --- a/ui-ngx/src/assets/help/en_US/rulenode/common_node_fields_templatization.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/common_node_fields_templatization.md @@ -1,9 +1,9 @@ Fields templatization feature allows you to process the incoming messages with dynamic configuration by substitution templates specified in the configuration fields with values from message or message metadata. -There are two types of rule node configuration templates defined. +There are two types of rule node configuration templates defined: -*$[messageKey]* - templates with square brackets used to extract value from the message. + - `$[messageKey]` - templates with square brackets used to extract value from the message. -*${metadataKey}* - templates with curly brackets used to extract value from the message metadata. + - `${metadataKey}` - templates with curly brackets used to extract value from the message metadata. -Note: *messageKey* and *metadataKey* are just samples of key names that might exist in the message or metadata. +**Note:** `messageKey` and `metadataKey` are just samples of key names that might exist in the message or metadata. diff --git a/ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fields_templatization.md index d7d1bb3104..231ea2a0cb 100644 --- a/ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fields_templatization.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fields_templatization.md @@ -1,34 +1,28 @@ -#### Customer attributes node fields templatization +#### Fields templatization

{% include rulenode/common_node_fields_templatization %} -##### Example +##### Examples -Let's assume that we have a customer-based solution where customer manage two type of devices: *temperature* and *humidity* sensors. +Let's assume that we have a customer-based solution where customer manage two type of devices: `temperature` and `humidity` sensors. Additionally, let's assume that customer configured the thresholds settings for each device type. Threshold settings stored as an attributes on a customer level: - *temperature_min_threshold* and *temperature_max_threshold* for temperature sensor with values set to *10* and *30* accordingly. - *humidity_min_threshold* and *humidity_max_threshold* for humidity sensor with values set to *70* and *85* accordingly. -Each message received from device includes: *deviceType* property in the message metadata -with either *temperature* or *humidity* value according to the sensor type. +Each message received from device includes `deviceType` property in the message metadata +with either `temperature` or `humidity` value according to the sensor type. In order to fetch the threshold value for the further message processing you can define next mapping in the configuration: -TODO: add node config screenshot instead of mapping below: +![image](${helpBaseUrl}/help/images/rulenode/examples/customer-attributes-ft.png) -source key -> target key - -${deviceType}_min_threshold -> min_threshold - -${deviceType}_max_threshold -> max_threshold - -Imagine that you receive message defined below from the *temperature* sensor -and forwarded it to the *customer attributes* node with configuration added above. +Imagine that you receive message defined below from the `temperature` sensor +and forwarded it to the **customer attributes** node with configuration added above. - incoming message definition: @@ -45,7 +39,7 @@ and forwarded it to the *customer attributes* node with configuration added abov } ``` -Rule node default configuration set to fetch data to the message metadata so the outgoing message would be updated to: +Rule node configuration set to fetch data to the message metadata so the outgoing message would be updated to: ```json { @@ -62,14 +56,16 @@ Rule node default configuration set to fetch data to the message metadata so the } ``` -The same example for the *humidity* sensor: +
+ +The same example for the `humidity` sensor: - incoming message definition: ```json { "msg":{ - "humidity":32 + "humidity":77 }, "metadata":{ "deviceType":"humidity", @@ -96,6 +92,10 @@ Rule node configuration wasn't changed so the outgoing message would be updated } ``` -This example showcases using the *customer attributes* node with dynamic configuration based on the substitution of metadata fields. +
+ +These examples showcases using the **customer attributes** node with dynamic configuration based on the substitution of metadata fields. +
+
diff --git a/ui-ngx/src/assets/help/images/rulenode/examples/customer-attributes-ft.png b/ui-ngx/src/assets/help/images/rulenode/examples/customer-attributes-ft.png new file mode 100644 index 0000000000000000000000000000000000000000..ca208c27ed3aa8be923bd1e6dc4fda05c0f56a70 GIT binary patch literal 85413 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
MpPaR?0tSYo68B%qqVF>K)v?j&26nNK z30Ui2xTb*82A04`Ch_1`^ULua!02;syOyo;gd%lsFpK>1v~2-wHE8353Ez}r;G*sY z%i1p&+ot&G75qacjpe_;jC;|DiIoPkYZVUAHPC5i}(Wo;e~g9!?0GP6;{iQ!wFh zK~&b{e__y6>ohIwv64D15OM^hi$DdU09^!)cG1wTSCcp4J-Z<@1n7FSkzjy{`^E%o z9F=$?hkjM}8MQAB1_nlDz?FZ!-&%^O&!KXuX#*3h=Ig|uP@Jw5i7Tx#o4!ODaTYzb z;YioTUF(yxt#`Y}UoE?ybLTW3&G--kK}6`u>HGDu3S*TlVMYw~e8m^Np-b?^2tAJ4X1JZwNV09{No zPko9$C>~X$QNDUuX{h-$6qY977NvDr7p0snsvv%`&)=2Btja^{d^IDMF8b)@!k1Lj zL?$JswULq(LPjNp8Q&ADw$p=3*G1Pt-LgRGXH>=y`(G4BUn(ZEDK#GNSof{#Ypgw= zU|V0AnQq|QIhtiKJiL<#^b(FYKFYuAG^nNVO1Y4Hw$Vi@?8a@jttC%g@pqbX7N4RP zN7ly$|A`FS0)T(&Rl7=LsyN+VNlQza^Ej# zkD^o(FEdod4zwRFWupz;{hT?zDt>X+SRWwY=(+RSHx#GR>{3+7b36ByGQk2yo!iHFfZp!%H_a4{jyMo<`-@iF51c$%w)(OP)K9F=4jna$v>q`+V5h;u=XS&P1;^dxQ@C&RPSpdGt;4oD#$);V(flb7isFcd3Fee?!pufAIQu8A9SH6;l0E-%t+bujx z3WOhK1w&knsaQwR&(Tzj^-q>{5a^S=8!4km5b&*z0*^;7E=2m2*kg=pH4gd***ka~V)!u< z_4Y7kf`4NY2wRT;`V3Y+6Gmx{V(~tbu$PJ+P@s7U#XEWR=C~_kLuyu(p*thk zd39^+^M(|?9Z2uLn6^ylEDME$(6ceO?=Jw&damckE<#?rucA2Mk!0N2R(+ZJl@GrZ z_1#c>akp>+FC-h>pGCbn`T1u(aM_Ol*8s-uZ1O8<#KXz4Lzo~>RZyn~Yt|zr`sTif0mtEDUEKyE z;S7G{8W9k?R`c?=wSZ_WDR#Z#&Ks311M!muqDRvosvi*qI06e^L)8D11F(? z%f=*DO)0xIR9wm37F~m&%=^RcfRky7hCz&)kTOO~iz!-o#0Z zdtdf zqs9LM=Gd`!lS;H;qQbg|l+hX1oh0CBKq2UyJMr@1;%HVk`-VeX)GqqtwUgPaOJ@6# z67?FxP#lt1k7t_+Mcf?@E`ilwn0(x#tuS3c=6Cy^omTk(&3o#r&6%d+2{Efq7>V~{ z;ivbog2`G*GxQn_r?dZ-P<`E1W8>8$+Q^K%rK&g>>sOPts*i>I=j!e{O-T!T{8%b{ zg4|&Gce4wn|A`3ThVr=k9Imt0KAyd4x$*IFFaiGj9a#rGQd;w&Hg+@Pb?iU_dRZ2F z&+$rYyERSnzGOCSjj)quzq5t4vX+!&c3qs-6tlFe!^y|pRmiMZ8Y~(boiY>7F`VH9 z*jTe)!(H0}ICcz>%DOUzo+R<0`~ZGxm%uEk4V@$GR%Carov@J{hGpu1@>)0!!!7r{ zVs{d&%#rCbR5_hb=D=mF+&oCF z*#F{`^&^k>zHMssV=FBS1L)n`!-I4X6-NnH8~02+S_l_aBh76ap<2$7$<6odh+s6q zNu37fYnn-qb%q~lk%{J|*YAr1RSeETKYf$WQNo7qtW{JZb{xnD;~n)9TXHv2vb44utlRBe1Cozqlni`qT6&Z&f&2nGXbB))Etbsw-Ce_gD@Z0wv&u}~%e5Gz9 z@ZR<-;>F!ZFK0%NY-y3r@Rgwgb*ZMSt(GgrjfraQ#Jkcd%%nhN89kBQllt1Ievr>% z!M0E>@1^Fw{mo&`SV}RvJyH(W)#h@Xz#bsEo$Oj$_2Nq?r1M#G_P+vZUuQe;uEpQQ zLI%VE8>7h()+*<{zw%v!7WvAAJgaY$Dx^b%9Rky-di0HHkpM{>r|l7Pz7iB#2L$ZG z-$iXW@8&JYW96AfuVK zB4PADKeh`MEddDA0h*H7w(X1W;nc4Jt}cVhZS%vyeu$@#R!dPypkkmdKJEa|QzJ0n z3NH7iYkJ|EZ5!eSLa+&00=M`2CD{9eE6f_SRmF+}ff`##3Va5046_MMep4lgz4_DIkC=QxJX4OU3VqFoTmTAiQzVb_;S+ zFjM8jp){XC>2+3#jL6osRmn}XuD>7dNy6CY@ZuL}_z zB7%Y5h7}%a&+GAINDKD6(0==|@;qBM4&UcrDD$h<;C8 z6EG*K9m`nw0MB%@pVEV;>f_DDZKe|3Ws-ulH{;HrNEG$wqv>3t4|JA z?=7Al*z-B9tL|=prGEwkEz@i&ytXbLalM-HqY$!4yH)(?n~m(!a$^7A$!{Atx|JA8 zkZ5r?w(T3|I(dlpk8%cFkqL2PbADU)O98qiO6&@~lM&uCdD1ZT=;b!s&q1a@tuTC* z00(+PTzDuTkX1zImx*e7MyW8o)uXcJQ$;Vb@}SEe?v{dhdQOP@=2Rix<>TfP*>`=G z)>M)8d5pLs^biy!);UlRCVN~{zbUUQD@ZUA5_Cv+{sX8gQh~aI6$>UVEC^Tg^W=3Wvod<^E+r@A2i1%Z zDtywLzIxMNyL!(sPqOM^U;OvB@a_q>+er!0u4oiS;n~SsKKnzX;znCUm(`nGTVZB0sB#9dsaJa66kow$~zF`v? z7o~V`>mEk~D{a|J)ts5ZnrYocZd3nfFx%16ruTN!vSRq`xS_aB+_S!W?|e;av%PP0 zHGPhyO15U#(VueKrt%#xiHyE|^~`r)-6aD7I+B#;Fm4`not=_cl5g?%<3ynM3pF*~ zO?(D(EA7lN4(-uMKUB_ngm5uO|gNiV?gCNq(~4evO{IgZDH-jh6gEk1@Os&iAe+ z(hSLMRHtTqEuVTO%rxNQ9&o%yUS8Jkp8bf{^~}7>4{mE=@bG0Jc1V0<%m!lg9qz;! zRuJaJSCbnK)KQIC2wL6YKF_^xdq^;P{z z?_rhFa%`pjvdW|BH}8@-^c6J>9CaUZ%b|mh_7uLoF)cb%!y)6yMTC~r+Hh*m(KFr^ zc3-v7gu;`OIdxS&9IaS?w`j758O3iy(LE(zJvwYpJD*ScBpfidF8|&CL*)E4mpoc2 zB%i~iQP3#Oxj;7%jG1J<*&ArVQ$$PkzT$SNtn~JmPKA{K**ZXT&BqX7w%kWK_+CNnywQ!fV+m*rdT{H$1}#D_v_^LZaQ8L*Rxsf9 zJd>&p^Y^?4rAaoQe4oSYN)QWwZ$JC7Qrp%Rk*o0h;ouubk;UxZ4Cc2_w`RU2X5^mu z>NKRhQpzz2izBzzgf4VlWWRqrtNy}oe5w?Ny1lIxO)a4^QfA1GPbD62@ku<9%lO0i zL3!OJedn#eQ@v<9QVi(AHOHj5a*hS*v=Y!$rvy3Qad?ew_)%F8799W$OXIaH!sJqw zx011i9UgrSG?nj_ktb|*g&DlUKgYopnIRI!FhroPK2eg~e7atrv-l7P<2nLf)<=JG z(3Dvpq#j2KGmG@PzeZ3_CE!5-et7oCL4wegSv8wsZ@E92f`7R{jhP<-azoK0r;sXH z4Omhdm7cuGccbIkf#L|r4O-dhPNqjc&u`t|k?}*L{F9TS4@*rNOg55G|01(_KR1jk zj?xw7ZWpI+B$~0BURkVy9JmU#5&Geh)G3ZqSzabq#?RVDVQhCF&xlqpvNU2qd%6HL z*6LmtbGAJv1e`OQQvFyIqoeVY&hk z8mb#uuif1aPTths5r3+-#C_f`Blx7_DFv@ZTFGp=0wDub`1E$c3!U_4Z*s`EjnuHa{Z23YE1TG+{7whB+pjW6z?}d`cwW~{09R({ zj-{M@t^ciq&$~B{ZG1chwleme-HqB6^3=bL`pHA3tIMmZ1t?AW*>aA5yu=b`d5OUJ z#gWeN;lM7}l#5B#gTMFx2~sq7X_2HK1qR>Z(W{gA^Z`YoMkpj)#~G!))SHg!^W&|2 zLTjaF{9C5ivVAMtg|SdQ+`!LqTiw-Uk{;77UM81~7e*JeWlpnLDbGXux5Svqj&kr_ zD$BWXG2k!wyb}3VZr?jaMEPkMZB8}k*OW<@d@%XivGttkffja!{EJUq;?Vp;ql(6; zd^wh96He>PISk&>D|~((4%J|oP8`T$eTF+;H*`U(O#Pc{LE5`(pL(Gf{1@$HRPO5^ zZ%ROS6p{ohN{lKHDO|=JPnNmj0m$_QDHvvaur{nN1nVRjXuzT^^y(h^(cM|g2tn5u z=pOMWD@Rkt#j^(*rvT*Wbe)T_omMg3R&%Q6MpDR$2!K>BtR}Npx*izBIlmS@Meh0i zRmT5>-sPcs&oI_&f-jB}R&dOnHzw{S=Y$8TWiNC+XK$l^J8R+dAmr1^27(n#=g#3* zaX63|x@9!Mt;r>RgAn}V+gto0q!|yUG=6;Rjb{o&w(1N#Y6}1e+a15F9fy1vob~99 zN_xrMTm`p3fYZHtFj>Yyh2dZssqIvP1;;}LBZDX%oMTZESL+FBycUX)iLYNNjh2$) zOX`J!R%Lz4-5$=hD-3lDD*_D}n;t{`A|6gXKv}uC^)8@r>rcmy*P25Kk7l zG6AduW6m*;5Wv+Hhgpdtu>{F6#~VA^>ht^Q)6AUl{h%zq5e4vGQD^@eki#lR30q@)7XOa zkf)~mtwq*>!$r@%4{}UE9@KvQkEuhE%W^0%a^{T+Z^ z&Oz0g>(UPU&QX=H9B_!5I-7T0_+PXT8H!{N0l6f?t$qfV<1@@Gdi2&7**TmSC$RGt zmw4(gI4=vp%j&+_mUH$ILYW}v*`1}=u3Jye=NhbM10))nA(UQlW{DK|nkftNG3c-HR2hJ&MCNx0*aKki?_4BI7Pw&!`8+ul1PVnO z;$6Ef`7h~*js%7gbr~9a2%K=c{tKXzr^y8Fw_?ZF%CTX1L+D5(sDB-hMR)yt#cO}e z{Tm_|07n9WpQyA0)y6mY6aWREWvEFhWEX8%8yE8*zjOzjCE~W7*-`nL!Au7A9<~DX z2ABch)9}W`N&tX^$&jP3V9+M-13If;;{1JapBWHp>00~JFaGN%Y6+JH6chn1`p-`O z!d<5_0r@iUVHy7tDSyXD0!e@nqARFW`D1M7CxBL*#Nq#g7?p+uR$BKI**o80=rB$i*-Ka5mQ4Qc&AA z3B@Fqk0D6!xXJJj@xsM_ALjgLF$3k9cx(q~7(r&|09wAm2*|S_Irkq7{8#7AFraFq z2T2Ei2#>t}(>jon7DT@=Y|3BIYO-HSbmH`KYC3=tcWPdl8JzynztLBmkq|tMq zp78+{M!oA|6fw7nk@)5DJk*=8nDJk95?J7YpWY)x_U1tb)AgHo)H>`V2^k$mY5?L< zzv^MkLQksd>d3p>eavAShs*srJrM--uZ-$lcQ4Pj!rvuA>)3gC)WU93vhiB9$K#N& z$2AQ)Sq^}T>dkm9Q*Ldt`24bUG#_Bl-=zyf;gwchuK>)P)-E_t z1OQy?{m$H9;b4SJa~Qmr$025+`I*9O%8WhErW-skpO;GpVou5-wP~!DvqtD zqin5W9nQ>qO<9v?ha2nwd6s(j(O_fN^v4`7bk#GSBlyI6vHmSzA0n~ zyjuq_=E%fefaYV)@qL*cxx2fl^kcX<^(TZFMa=rr zDB#j5r#tJwUbyGt?1<5Abx5P!OfnrnJAtCzICOW6{U=-r2#f0qdMOvj1#s0`v|7+> z2+1s9V)*Vp0L0Glus2Ph7%~q4D&4?ZFdDqKO}uBXQ)p0K)E-M|XdGAJxs48d|L9wX z>lMJF3_oeUy7cL>FR%fSY}dne{p8GOZuIPp_?uaJ0Lm(?NGVL4A5fE%~1Cp((=e!p>k zvS(MK9snqtS#eRf$4RKl0fE%TG}xiG0?IkAQ{X$>%d~4N=5HsR6iB!%rd& z&{bY`B$yVIU#?eS(JddIAPgX*)xvo5uus`Aq>E{#l|omJL<^s|c|mK0j4=z((&t#p z;%IB~QUC`bS`Y=Odk!sH(AS_#>&|$|pIjWH%1_p$P~){m@fC~bjTvH|5F}tRSq#9u z)67ej3EN4db$O8H(U&OH=S*p8^MMQka9UM|H;*igo%}WwO5SC*3ost6&1TnPVY29( zr83V*lO4t@yMR?likF-T6&R`Z42Bm0G>hF<3a23i43-t%rGb48m}|$@ue6GMfe(YS z@Ss0OQ{<;fmPo=8EQkSfBXt@GO|R=hXI{s(y-#VH-wOf?u5mCwc<~CraLj*kyW0=I zVm^mj?qusMO$CKy!3SHbO_vvE*INrDfgV%~V(_s9aI7ZFuMl+{@*UtDq)66o2J0}- zJ5AO+pzr~3ju<|U1i9Sjp#--B_Ld$j$_(UQovv|Pb4ZDz?>TCXl$n}FVj9Qq@0Q&4%Zs>Kk;GJw5Nia!O9G}~&mUX=Q+Q^qVMtBP; zml1gpERD}PYS)Z>>zld8Pc~o%pSUVdQm^o{qRMEn6TH7`=4lwk9q(}^@fTVPHsR)wNAfO~;Cxl|NhX=}NchdC^S9=*4v$xg;zQtbfPcArw%VH&t_YWr z*jxP3Jg=K?eX^jQrnw*gr@j+{U}Oo9Q7m&GCekYT5MqAkUkc?~g?iKehts%?wo+iR z@j>WX-efX|St`;@K!O&~LqUyEvH{54NHOZu)_6ne7T#U&gLQjS=q41sIEcN5a)&Ch z>Bh+u5XtFBaO+=hC6>QoSfR}`{32fZ$!zF-P2w8>TU8ng+tW=)i0Zck%}goiOO^PK z;Tfh>aE*fZ%nG>E!q!1pBA|0FeuH5^nkRIx#kw}|Dd~R{#)p5p)T69_r_8$hRU&#K zNftik*~*&+6ae{dcCsPGxnM`h+q_|nSQhl&e@xLzfk327Ks~aZ3nB&j9$y>=|0U3p zx(+j2WNN{l77^=ePtG$NbH#0CCoBUbV!pk?mbk8qd5rlNJ=)MAQFwj>&<>Pe%^%iZ z3TccOctGt7$94vy_h&&XF4UB|=K!5OzT{5Qq#JW@DguEDeK_zTUJhEK2{?PJmgQe6 zaGCE@!*D*i!>|%`(w$hAFmz{t#ZP9e3>qA9-L*9efD{}w(FSg2gOHOCn>VO85o~bv z-Y@szjIS03P5tAe=)^y4vKfDxlA}hn@)ZD!FCzbRe?EiKI4TG=d_HUu%F9dnXXkE% zAwENDVBs&tSjM)D*WH7A@F1aBEDIJ{^sVk58l}NocrzsLXvKVBoSSgm0A87|aJKMr zgiJ3dp??86(1x~L@aPw#-y!sCJxcg3`KfGu|Tjg`K~C z%~}#VvN<@K_FM-(l}xQMOE9E1rTB!mR>2w&(C42g^+*l>73ihPV+q0Di-K^n457_U zZ9a@5E&pJsTxmf($h`xobC;h5L>JSALaCd;?xPo7ObH!I#=&brK<`H|YPy462^oZ5 zNb@iJ)v3w51-P}Wy=4&zDDT7Ru;$E%$N3~DsE?Pb$@u*G)A8!(_8$iA}~jKr0vQLU>8 zLYG*!&4TSv4@XMwUKE2g_r>W>G(J&d>Sk-pJ?eT4_iGr?1Xq5-Dd!G|^xWm2H8|#3 zbfYhtWK2Fk$x=)IvMzVcoC2z%tqA2KH2XxsxeiJw*D5=NoSzdz?7NaCB1=kpIsKT4 zxi+BBAR&Mu$dXC3VX{GPX4nihXN=8sqpor&Gd+gY!@$h@EM^&ikZf^?AeqN1ln3NM z96nW($I`7M=b6?#A!aW8nM((0`$J~Rth1CdKFF3_Ae5%;Q3f5q+*1TJc)|QCU&wdA zpyH)5xUwAj)&&rCKCHYmGM^~=r%Bv_xwt?mStLsi-y%>Ya~*N6VD7O&EG}NcK14bh z%3&3mXI=5`wWPg$H9NQ%L7kxQ{QTXANHyvV{qpD2VLCRag_Uvra#({+sIfZlO0Dc% z5_8#+9a3E+>bRsMVmyKoI%SL^jc~JYr7v;bf3bBHQq{F93T>S=Dieiz;2eii_^lRP zf}miwEX*tR_Rd5j*nxDd0u|FO_|mm_txsVwX#q}*n+lC?skyi{VoT5sY`0a2I`#DZ zCE6ZR6mQ_yM#_wz3vhjQk2k86t!2(iQ2h-1#SAG<*)&`*7Sf58&jQhnNQbWseBYQg zPN9}>{@3v^mf}^7RQS9(dx!9N^C`tAp>Dux#dZ}i6-Od9iOsn}S2l*0;M2TbZ|>hN9oCi7p1VVS~+ zfiZI6k+RM|B{cXCIrupx|5HkV{~R)cod_So@OJr{c9j2Lu>rMJR}l;8i1a$@lntJ(-_|cu*T-SDG1C-WCWwyXz#NrU70c%c3zCQ zD&lNVI9AI}!XOJTLW!=e*+4I)o9064>a50JP)kvaQ6;D;k9e?ZX_$9 zhSZoFF0U)QNyf^y_F)T5aODM9{=d zKp3d~em|9@`P4qeP?T~sef#<4#LR;p_1W``oYX##idV1+rT~u;%dhB)0pKOlcHGMI zA;&u;hRhOzqW+Bqx-;Z0<~DTZR4uq@grn|JIjXcx?_7gQ*enk9sxV>k@mAZ}d*LvJ zNi(dR!GNOJKf+fI?gF3(#0N_3nxb^{Vs8WJ9`4skd2E_h(mQL=b5-K3utkFQ+wD zS?+bc?dyN5#r4sPm6TB4dPbPn-tt_iUS|D9dmu&Ll*H8ZEy8^a=rEpubvbn0?coqF z4-yTt;Gt2W9S6sJ@;zNv4GVn;K8?V-2GpM7?seHVi1(W~Z|hy|z21MbE_i04tTJU! zmNZlekq??+bCT*@fTKCl9~J8yhpxktn5TTpMw-2X=$<+0qKorZ9vqqCN*3%r=EkeS z4Tuh(d*u+>QLSt_gip392Nkiz62~j?p!z*mHeUar|4AE^Io{xJN-yopts@pOV{T3_ zM|FKu_v< z>dw@CDxa(<;K-8t%I#XC5mT^q?`zV!tJO%UJ^z!DD?Do@2QK;UWiPY}@49U)#YFGV zF8;^>x0L?6c5Vz%2o5V>ud=C}CPmqxzIcNfb{Fo^^LQVf%FA`_G;m+BoT<0OPjvXx zNs`MIA#wfS$b1SNlLQc1qg#~tzp$+?lk$7(QXY?YrtMc=B}8xAysQY!?(|O93Ne7s zcD=oi$%67<7v&DoFeUa^HVBl5)?cM}Ssmg7YKclr$NFTxYbhqa9*dUZsDQqN?5O1*Yn=MU>401QvIa6+_NTpNH`K_iRZN_iE6Mhr$z~#^ z_TNniM@m*IeI{6c(jp1F z%vqiF^W(`KwI8(?!89(kf_hJERGEqLeXfNIt?Nw71o|0r$G@11joq+`v!(NUMF=8= zki{$C4OFj6SFos3>j|xjFa@%6C+hRP?`)l{ZclAqnCk#QrKZLqZvFX2`edzueJ z(uQWxPXq%gO8)F!4{D&8NiP%!-G$kgbFesegvaohN>OlFEAm}DD6aSfs<|-`cdkG0-uACA1gbBYg1y+PKohbL&Pz?meuU*wUv@kY zKB;Waw$A~ag^XE=FwdYYyV?beMvQ_GqdW8(r^0VRY{T?xL$D;lw)xLo8LM&ED6e+u zeG#9s-Jr8G-`&W14KIGkMyxLoIn`p1iA6?WryI&Wwty5Qu ziO{3iXs{kd=9zvj=0~SVcq31uQW8z)?Gt!DP!J(uo9EB=yfJo9=kKM6A7%A^|6aTpbyTg$F+F%l-kel;6Lg=5e}naetm1P zPv!jl;8nqhm(0lEjeHZ%!6#L=wBe#q73vAzcY&Y7>sCK}55kH#@IOCN{&?Ixbq)&D z_(tRGTQpYWGj%Mgu_~bJV*$_}K6!p6mCrwOd76 zuubv-I>etHxrdJViA_KsLc*Zi1N4M(GH{uo0+YJ?H1XgtFTt*u-($PCJTTy@gaq-V zI2e?&n(93k6bgmy$-vPfilYpYUYYBP0Uokdy+GN{YS|jG4Fq2uK%l7o28qRpK#&F3 zlV7{bsBnU)z(b;d{egeLRDx>l@Ng!Y)wVyk)MLwn715Ef_i_9KI_m!|ad+WCzTYhX zG3I)?`fISAyS4?7?v(kE@R8g5ZA7{VKGE`6aV;6t*UyBd^ZZnAT;Rj#0_aLWY?IaD ztASV${5QO5Cp_$b`rd_Ftg{f2J93U&LQM2Qm%j)T7uVV|&JsuI7|*p7+rBH?9e;qu zc>y=P4-z9!`TffzywA0MeF?kX)?=)5VZ()E~0-KXZ5{e_$)>qU+G}n z=pMs&6OMCKVL!^^zCN}MB(fYEXaLW!7*;&)V4Ntm3h!V=y^9?1><_2#EQko9w0J=0 z6=*YM!22F4XZA{71q1xj?1DI@yUO0?wTWB?T4BKe?BO86YQY20IKrO^Iz z?~k_AB$1%e|DimJ!BswcY`yn6Udpj8XE4E~s}AzP0X1bbn3DN;@Rub3sb!TzI}a8b zcVuA6{!$0J=^CXsn6jb9`cuf>^LMi548r^E4z8GZk!gf z8t8k&fbn~cG?YO&dz&B4{M~KSB|c8qh zi*M)gy|1kk)~qgs>&XD(0X5sZ;Z$nzHv?8heRNB0RIZx}=dpm8hj{#t${l;7Bu&Ka zZR-z8i|vuc0IZ^@4&0-b~<9Nvx3unDxq0piVietw=%J*A0qZyJ(XBL#`9V_0r*lBS&>Y^DSR7Nx}p zzIp%MJLi+{#YDQVXYs7sllD7kzo!otC8&KepLA>@qj=Ncq%E$R$p5m-p!^5vfbR}%28`G&ST8#_cnOFX`WsVn*S@eM?ZRxGMiTj@#4}9 zO{-ukZV^_jw-&BpIs<_-=srj^?lvPM?-Vx5 z+_2i^5vx?hn*1V(Twp;kiZ}&IB_Ph|IocL88saq?`r`G;;bTt=nwt+}wza087P#*< zU1)w9YSU=Iz_1qavPB|O?DeyEr|7?2Y?Xn?T8Hk&INZ*UjY<|X9_ji+Q%Pj= zzGpqi2vYZJ@TW%}3<*9Q)GV+0zC*>6)p9aCyV6R*>QF#k>NSeIZg?#O#BSWegHWG> z&^B(*vaEY@=0mS^mI*J-^3Qg?x?fIXF6%*ekS;CQIh&}kWzjy|Svk8fOv^Q`W}Y$Y z?S8Z!U?GMx>D6x@)BIiOmXz)Wl5A6$M9IC}b^wGUS?rLm2eud&yqys%_-g6sOCE%c ze1NOO81cx1h>_7r(rq!|noLPy+Yn{Y+T(=u+nWDs0VZkL=e(JMCr>{C359}S!t-w{nO1O;PYj6XHa>n(PltEjw z0TvSnb<6D)teCo0IcU)8e<^BAt1e9c<*PtUi z0Zy1{0=*Z?o|=QuEaQB#40-}(#wXVFX|_o8CgU9(GPpFvl$ZctTJopabF8K~pgvEc z*uLRH9GvW3H+|(fwrBIT=c|G21dto8uG9#xoZt^z?DB!NPuIO}7r8(umehr_9yKhP z^zpa_!6w)O!hC5}TKg})v^I3x>=@L`VliR8yCq^obOfod;E$qv>vCG|7*XZ8+Zz{* zj?u7vk#?BpgViA1OflE3gtbYQad>jVr;HZPF10xzGdxDlyN%V};I|>FjM!cM@nB_A zC_rqEKxJiwp>C~h+mmHV02b3c&6&e~(v@DnbS)T5KG4VhTaCT{=lI-FVj|l4R+x`x z=UriXN}=v>xKrm{o-4O#jo)GVqIH^e**f`9gj=bI>(+CZt5O>4(q7B5A3^f<)Y@e< z#3G~Sr?txWQRN=?W3VGgo4d0;hk0(G?qOEyjaAU@JmM?9XklGC+aY@aA-O6qbhL&* z!KsHTUe9*CU0#!j(Lh2Nm}N+(XfNFXfW;K8z<8h+9v>xc|3`FRs3=QX8&}zuEE_WpMbo5;JLa=kzDCeR50ch8WQC>B~scx&5W|2;-K)= zkh&h1XoA{&H#^Q^mWcHY4=wEl@v)0N3_>ja{AkD+Ykb!!mJ^?l>rDI(e#;7gsNGh6 z9LzR8u`8zkF4EOQ#bfd{E~n?gU}IV7%y$}5r(dN;pFK5zhgZpY3S#+{?KJ?prSB9h z#xki&w8si1&vqv$y_j$RdO5IrdPaxE>;=}Zi;@Ge2)|PTIDGT-Q_@=j+X3Mc!xgil zP$^#7VZ}elHW?#8I{?u0Jv}tppx_UcfywLm2t0m3ud)ZTn)wfv0%`QmG4P2@OBdHq zwSV;=n6UMqzmbtKuVj%P2__i*m=uqpgXHC_YGLn#QE7*G!Ki#|f|WlE82EmW5CHyg_t>A@ z-(OJZKH~7?9^9k*ftB*#H^2ykLy1BQ-`p+;`xX6=`54$^FAyJj>_4$@3Z59NY>lv2h){8X@`t|JroEDa_R==Tj=?x zhi?7-ivvdRw5~!9lENNi|G%TMf)7kJu06Fq`97F%HGnZyJ zz#^4@X6XOvSSlI+`924}l)tn<;EOddqvI+h@!J440p(Y)70qFk1L`YQR)0U`LRK*M zn&r}sYusY5-(y<>&0MiTIS?L$)*w3b_8Z;0dhY`VJVL@(BvOay`PEV2XT-<|o)gkA z0kj+d0@zc{7GnY29h`GzLjAu1hXiBuFc(qf zwf6yN3KZTeMRE{OacfJvJ_1b9P1}Bz-`x9aUi05A&`5@(1 z@pP9LQ0NOat`fNVdD_8@f7`J6aB@oB!Ft!acWQ`DLb7*{(v47xypq?LEaGfIfe&=C;KVBy9a+_0#Q^h{YUCBc+44b?IQ!8GU=Y1G z3!VT6mQvK!ytFq$_OXB#Xb0tWCNRxoyx^+9c8W=C@v;XdK*4%G%hpAkxsLd(rwiYn z>@Dj6f;Q4;>kCz^w7;K0z0c>?3t&abGp?xsl31gn2A`u+!YembqUa?#Fsh0ksgqlJ zyhic^A9S+hg7KdKl>?B9RLm1m`1PbpRyUDSQ(pskOy4Ll!m|SJVAVgvi-sKL*hBLMviJb_-t0H%2l#_()Uz@xEbpCCU zUaW6Z7@v^3ib`lEfCwhMR&G4{o(`$u{coP|VwNay7o8dd><}F2m(0p8KZoJ#x*!6_ z_Gdw!9K=C__f<;d1h~?6Ae&)PPv8=ZOX1YxmVK*n8LI!t$(U5;wONF`5g_l4`aqwR zrUqUX0+@cJt+xAezpBvVp>ziUFyILF03Td?wm(`5#<$=pQUutwSV7}5unUay2B128 z#{_uLJ*Qv`zIt_w3eCX!wjD0H#1k<)k05yI5=M z6$npw$b&vU$3YKR0Wn4fbztDk0_5=VqgS|6B*0tAg-^x(SS`bb<-g&B1uc<-!*Fn< z_^nNe+$p;@nWiq1oLd*B8UuZ+b(3`Tlk!3|>i|rE>F5jL=r#r%;b-h}W>B2(XJQVTV4K)|ETnUD^rC@0+OecAdjI zavmp{J~dPTxh;1W7*R1)1@&Ob`!&|!-+&J(ek18!;d8pxR{i2xd|;LH%&`ld)vrGb z@o5Okpu);!_OSEVbuZYwIMT!CA&VMT*{YLpKsbTi%FmAjdkwoCTwP`J3hX}0d6RD(0)d7u+l5vdDC8Iz>CSEcO16I`)m1yD*ALzz^$DRAg)1* zXF!P{pX$3mtn!MV=f90FAQWt>E&PLw)QP-ed>QLkP5h3mQkH}a;UYb;fFhO|kBP`o zjFf~=nRo?8MyY`td$P9Gcnpo4wSB`BbwB;3+Y7Xigd(*E`9 z(r}=l7z9d?u<1g$$i;jf0wqqiO*-)cOPuGwc~KmTnHPWpB`2V|Mm_g@+6O3l#zVzy zzFpm0X^U_NqaqU^_FhC|W_LBG#7TrH3+NSQufR+Xfv;I~A8rIHQO=Z$Djfzp{X(_qNt^XPHnUYO^Im;@qJ(GYmLx zl{DrXvrQlOyRyTadWr5V1-xAMu|-7qzTGba&9>k=Qq1XDlrz`$RJ=g?G_c3@8~9OA zBZ!7r#>(yVBn=h-rea%lvE9jITg=RZ;4W3%PevJ%n+Y9zj-dl!S4_6qznL-A0l#xd|h9k0v+DB>4$^!*Qj{? z`!5GvBewozG5kd#79`yIqbbIO-VVS{4d5^s>>B+-;>Xsoox=f(Z)wiYo;{<_Qh6!o zkK)96w(}-dXjH8Wn zx+7gSqBwh-SNFejV}x9Q$1F3*c=56B)*sdybAZ9$1!rxcMD5GJOC0~-cj?e^&8p*X zVQVcLI0|ygb#6NHztvI(danMPRP?vwx%cl=!Tfqk@HZn=#7W}#CtL3?i-wqeHn2N)PorRyBx!uLZfM z?i&;FKwmOyI(n$^-(_t=pou)D31Ba7^%6$n2k5iGim$}5-M*swR-}aFraaqU7qZIk z1iVXl#KZ|h^&AM!AQ>~WDdxw-vb;iH0LzHpx&T1)@&RacDjL|7euY_+{{(>^z%g4e zb{T=UUi<3b2gqnmiW+x6KlN+}`nIkPeU_(|&+Td2m0!DgV(f>hV9FIX7e;~%jn?Q5 z(%s7R^mOIxTAAN@%yyYY2q34C_#m}_q>s!-QNfx#fyP9O(%E=1t)sEErf4MLxEt5sZEN7SQuYT^%|Mdw5wBzNm(!2eWXKw^{!)u~g9U znE3*JPX3C{114JxH4lJmEjMabtmBjpWRx(_V54-*fCc|`bcj3hh|E(ke zAaMBiSus)y`B*3ad-GBMyMQ5*KYdq>3>UBiV15t;v{Ge%=>ss`8##3KZ?Qk+Z+QS1 z^1(!D27gi({?Q@eL-sHIIa3w{!S4wJw!)_8JzRgSIlpf!O7RTc91=Y{QHT5FVp`s+ z3tS;W0NxUIS@~C6BqttOOB^T%6x6ea8WafJq+Y?e*v;H8O;HIp@yLs zZ%CK}9x|IL|2db-BuB#i&-B50fT(aXmDHOrKek(3Sa3RkuIzn0YT%3j%s^5ous%cs zk#lzZ@KDw9)I}lZ;YIU><3l3Wq)d_?;0VW3s;Xyg=;eUda*Xr+6!SqaCUx}k z`4{3h*GfGrPQ3iBF@6KVL-W%be2|g|!-phZu~H7W2Ok=bIFcX>m4fP$^pit>=vDae z<0%M3@=vJ5AHQF;UR*yq?*agd@zV318anJd$SK9fO-i!Od;k2s-+jKM$7H+#;GTrj z3BAOl=89}eqX8h0rr_!|Cy*+M|GY8=l}1+Vm7a~*?0eDpAP$8GD_A#OEe^YdHhV<= z`{3ap%#{P)AYtdHGb9G39wl!@y_I@1@7xfy9Y}y;<9ocES**kM)*_S^%!FNpFua-W zoPRAg>pjy-q*dg1>9gm|bFL(5(+Rtuw<09DQ|DX9pQcjwEWTuBF+HbZO}9|gV3^yl zp6g6d1!Y#2oD6Ez&NJYG6r2+%;BKWz7!cEorT-ACj044fXIq-jm8FXL+hLL)eJvVB zqNTZFcb5dd(#~~wUUscI04Y_PWNf#tv8u=O-?*cs0ChtYSNoSVvy}$k(@vf4Aq4iH zYo6lx5+CHIK%5T0<%qVR3h=@+`=9M40;Wza($b&o($_X&`Gy1%>Bl_D{5A=ob?O9x z2LoTfoi`CoCrmV4oO4orOG~^e`m|$!Q?Hg1+LwLnrP1f7>P!4qOgidac0{`U~GuRv5iIV!DC3<8XoD$u^Mf}j*KX+NL#r0e&nr_VoW zHBFOgT;552wMrF;qqbJP$Kro}YR)Ze2u~+D1})kgIGbm2J0Rz1y(nlqLoA;`FStD_K(gzR!0ppjFLc7qg%Er25owy<2#1 zXDZ+l5Hg$7eF~@GqtT*<4$zF;oES9mHa7YCawe>iLBKnN zm|okG>bdMRlcKAWG)P-}tlwY~MJLVSxicGANh_S7NI?13F~>hHf`8ZWkYS@5d?{HnOyEn)_-YdRlv`<}q-y>x)#n`^MhIML^5N4@0Nm$|Wx2F{H8 zAe*0V&vwPD zkMfN`N3I>m7>m1i6y@A`^v1i)2mABWlZuMIOSt>$30(%6(}s@uB0|sd5$HMkVjkRxUpilU-R}OZvq!dp^}6( z4Je}6Qp9{Sm4qS=z${RSbDtQ9k8E4NBaQKFYFABF<-ara&+^RI&MU>gM19zqz#X66 z{YD*x&210pnRbL9nZ`cjY2XsCaO|V$REm6)J9V@_8b;RdkGeAK@iS9(QZ0m-ZeZMe z`WbfY+R;MRDy`$@;Ek-)iZoeSemb~01V$6i=o`UVS71$#I4ePlmh@siJ)mxKPIH;y;{ww6Wy|nl(N%&$V=V{;|>XrS?^Tex%OMUeO)V--Xe-v3c= za(Ww9$!LSbVje*->c0cl`D&MqANS7BSBjj1u@vAD2%AC1Oy~LCC9M)I)|B!fyB44g z)4qvLawgU%{TjoUF;?X#Z=;H2K~y*lGu61Sz1pV}&vPz$+D3c?mfg%d<6hfmwHq$M z*xp!97qoK|+FMu|IKMc7NaG2xDO2EVYDT?K52n&dty2*5V zv0}(cu^Ot@JT_fz-~;6#TuB2uPx{YJ$RGV&knc#~64?EhgXpm7b&zHc2n4oxOEuD@ zJ_`3bmcvFUX8>1FR|i5aGzto9pcKjy;+?SZfnkE%4h@> z^c$L%kVYN2h$H25yKkYS&4L>Uh3Sv*Aa)p|6X@$W^FVYbXp!>xHdh>TG7WYP(uSTw zcv1N)2W&xKO4i6@@xr=p%KYf56tQ+MDPE!Zdt zER^pE<%g5+6?%DkzMFP?V{Noov^c!*J~6|7M;poI)_n^tH8K#6DIgWh0K$$ibuIXO1`fQ`92>+XRADhK(b_KU@g z=z-g2zzEgLliSdYjaw)?jR%2;()8u19-&@v;6%i5`+Dt(yAdOx2m+8N^s3?Fc$DuX z%-~`wzcI?^7yW9M${X&Kv0Bf2^IfmAE;L?=yu89gSQ3I7xKy4ZXLeFy|KxOt@6m8| zxzv7$B7v(bmjn{E52um{HHVwpAW;;&@Bq-XiXKx^|9Z&tkbOM}T|Q;EeE#&;p|fY@ zqkHx_cDhAB!=MGLG>|w--b2!Zh(~>&io$7yQ$L+;HV@r{B==F@{--YbI!N&KpX#?} z_1b1GKBTL(SujWLi(2g5Mb4TGT;gQxsn|^L@X~kjcUpByL@AG2`7$;?w?*7cSm0yE zNu;1Y*fh{c=CG=g!xFHvRF3YIgop^jn11apO}bdpC-hB=Y3Dt$at#*spMGXC;}gMd zy~-8+{P~Jf)3c3+!QnHYom&2Y zE2M3CnU4@p4~gn~{eps%tuNOkgC(0Hz~<1z~-sk?I671q~Y3 z>e6*v{H`jjBhW&RX&Bt_1M0l@zgB!S)b6rK@I8;VJkb7E3vjUGqJzlCD&&MBW)SG4 zV)O*fE`#)Gu}Zbu8e13{dx9f-#Gvn;FX2>!LLv23_6(QFO-YWle2+_%u^eQSoF`UY%fo5d&0Pk7ak=xUF4YzvPXWRcwFJWK3I7YwA4J%v0Nc zTCkPi+5fl65L&-=3XBUV-Xh0gSCBcvhlnvp&)Ij)TH+8xE?Iq1i+A-j5nkms{IJde zV%!E#oH;^D42C=vu?{RO>5PKtrF_x{o1I#pn^SMC{4CVuLoHbT{HQg@q4C%)Seh>g zZe-;|EP4moqz2W6Gm`VFQ(g7Zd0pvYTKpc1>NTjqa!Ik|$5Id|k|%&`b1i}y**ZNV zQ6PaKPWKPihu4ylLrNS9fECMf4U}BjtF&HXWH2%Xf-yWG_swk;v!;xUM`Un_rdk0K ziTFEEwBqJj!VRmX*e~Wrf!}eW0dur6Sg2VNxe}cw!Y1jp|I-iO7op4IIC(z!V}6Ps z-V7efLv;~Q-ip+uUI{w4`B{)GRuUi-8W+BQb{bb9dbK@VQld5NkrPD0A2O(1eQ~IH z$wG^n<=?GdarN(~fT9}yb>oK$77nQb4&l`Tdfpap=mcTE{`fOK!%UTzD$Uzj=h*o; zhKohqSlLe(hIAthU6moaI0B<>XIz+1$Qp8gQWh{x^{2yP0nMb742!$g7G7`%R{%Z@gr|Vx9%)NG!Mg{piV#EA7ggPZ-#zx@CMR+b%gy ztj1Gsg3IF$aw2J2lFZY}?)McbJaH%hX)7EBN>iVm0$cE830V+;8}4gRVB4@BR1zA|rbQa6h0<3n;RHD1WKuEJDK)`D7U04i9(dA^28CVy zGW++NE$9s8UrxB&S@Bqb;lqTr*Q|>i!E5NDDRkK10!G50P2XUd%7Hb}=1wmQU|6>~ z_yIMNNf^1$^RlTUToqk}clZW@^;nM&RoLxBvrXa7xS(bpV*F5tH50MF*-(Vbt(*i{R7Zdo!y^uRh10BG7J!{TNF>jNGx zO@R1LvQ9+tSE1nOwWKVC2ulS>p0wWnsT8uOFh%DlAE-3u-wkwv*?jPU+NO~drVQ5XiA*mx+1K0yh}4?Og}ey zurbM==DS^T>(s4uwj)KnV@r`7GV%3(xh*S=fLm?tmXfG?+TN$HRNP5CfSO8>^gd7p z@uA|17NZp(dn;~p9&NQ{k(S!sEs6pkSFS&NqVj6{>OjDVXIZg0DPmj>wby&{!NR?6 zS1PNvFA=U#?(dvP#rc?NFtYJmp)4ugjb-kSx@Qj9m-2g;uN1Y(G4k?mk{YQa2&J`a z;q8agCSRXzfV_~$dLwmSQ8d9;N>|s(9G@d(j(}{-7>vGO9!BRrM^>wcc(F)%r8akc zqKC&5;@ji3*jni_0Xb~l97tZvYi+=SjQpm|@_?h+{aTH1IMivZs${zz@Zlq$=Ifm1+88KRi%cXR zEELv(!WQ3GB3Nb@FW~D7)FLIcAaO$27ay`Q{AFJJ>^3~eT@2CDGydcK4}(^>pl0_n7o;FxL5V1n7K1bRG$^n*0M&TD1}) zH^;|B`JK%CX(T*Cwc&7#?6PZyF&QwE*Md35!`gPj>%*Ruw%`ju;3d|3PZ_=47Q<^^hp;ERL-9xwG9Fn!Bw zyXw>Swx!=&f7DJkR*K;9f*-~qLKj2tYD@?qB!fJCa`Cb7Ay4zuXfC-XqI+h$miqYp zr%9q(dCcuF3I8~h7@H>7O+a7-0){S zJKpnc5`@cHfHHIY8L(`;xc>5=+*wr0I=Tl?o}%akrCl?IqmZM2gPDj`@$`F4;BK-L}2?dJG077N6fr zI2!>t?#9Ral`o$=*3o5uZ|pSoGP!P|aR1YxjMU@F#u@y;Gdc=RorI~W{8ING`p@3N z+E5PNgu?Oa&aW?Y9NTw8q7?%76xFAgb{AZCji~edj;b#++d`{;$)|d}%#& zzg-p0no(v@A1-wiDa4B&FSl##mCj8A(jL{72Z7Ittom9bW7!?+A376l1G!0@^)63A zVsyUxt-?eHahS;z73@?I?y;SUWlC|$?H0mNXIR3G=+_IhzoHp{uKDhgEHbdr{w#_c zup1PQsOY`0QXp! zPza`nL;xOfAYV6Om!?-e|EE2+H?C&k(Ve|7mgmiNm%#>DU7YO-^oK23nFFO(`7GdpK9mb zzdhks^U~;W=GpG@4`U9P_A5WxGiGw=h0(F{{fft|AfHl~6uZG|HPK^X{9r5_PvU2x zaR&6k&(+U>RG|cFs4{sti`pxd`=2~ax99vdDK8EKACG*}q~t!;+@9^ucb11w9f3TF zI3~sL>(T``_t*Li0eHuj=ChsrpyRDUeTs<5vm%_%7dmz@^;fxCyRN*MO~p?; ziq@=Xm1i_(1S?iuMTweueYJz`aD@v0u*V(UrC}pPZ?D%7r~JI#NJ>Y#%!Q*?`}SVz zzK?LJs?eEN8Ff-BF9{Q<7O-MhSV6f)b7>DF2>UTg)L->z@?8e`_3c^BXNlZr%yi;D zxdH{es}a0*^MolcK}>i21MhRsvnv9oz;){khgd4r-JNdQ?k*|k> z;(q!00J!CNr?cvbUdA)IIyF%fGaTSe!JB)7@(k}4!a33 z(>e}Ly&~7cO`}f)@&}3PX)}#atFy z>_>fbD?@^UzOEEe3?`oe_;t~}73>l7_d|292!2rONv+fAN1~%^p8!3R*COv6F~l%m z*Oel=wM$Z=b=5$?s^#mCYSAGC;9h!MsCQ|F3KH+ojdsSecDlMYUUM8I+UR~=&xxVn zKTrBHaEs4KEu7KmV}HE=`91j!U5Wd;FfbZ&9{G-tz9Wr)_wU0`-PNdVJ-|B*M~LjS zS<&#@XAv&zPp*-^LtK(ny78*8J6~7biaEzdfGI(Kv>!VolEGYnaa?8 z0FoNt+ab2}2k#{pn`tobqqHY~j&PDB!sV99*ZUajN-MO)3?6pScSEA(Jdkvs#VJ8{ ziMPsW_Td8hLP(5RT3-~C4$FLD*%pzo)R+Bry)K%lCDbU;Xr>xy6TgLelQGSN6Y1q1 zOgdg)lX|=X-p)+w>?ak(uwVLk>=SEO_WXUp52`X>UVvIBWk4ka-GZ-^FJ!NyeZ@N= z;$}#tGS(jbp5yW-n(YqGB7C9j=DLR)8YiqEZaZq#LWk?x;?pyFPWi%BKmAX4!Inj1 z9eC40sFP|GAm`;q-HWFBJeGcSyP48cg7q5zVm{YT1Oj~8=0fW1tf0uB>iB<&c9LT&ucUd}B@G>>LqIK72qyYYwv0*rm^W(9>nn23l3W zrcPa(HR=rqxwl7)a+)6BbTcO9#Su6xY|u_OqmIS9%;Izy+>8Qj&9iEH*Tdozmz9Zo z9|m)`w2_F37brWv>D?6D0o$PAP+OxojBWKJ+-%173u?PJOI_GCq)93Wz+j5kU{e_l z=Hp^*FHkv4jpu<{S)D4AJtv+Wqbxcr2@O^tFr0}=We z(|XKszo0r60dkTRg0Gm?&IqvUvOlAs(H{`J-wN914Ho+B6S&Sb!D|Ts#pUSwwt{RT zPxh%b5GK}Bvm_Y{e;X0DZX>#|t;&AIX{aVl@4mJ_SyCeGFm{)@(*RX_at8!p@J>11 zk14rMb7-sw+gyDo-w?Y;D zUrqDT&(kxNv@5fDb}@7UMM`udB~POZ#~3BnB%y^lEWwpbsP2_q27SnfyVE5_Oqe{I ztFGj4zLz}NJbR`XRb6J;<~HYWc;O9hr6lHk8@*n3uvZt6D}z=)qN682PjkTToNb5q ze>7CbA->90zS2KnR~$g&4SPZ1&w76!?(xG_)FI6F;#sKA?etQU*QPufT5TRh8$g&- zT+j9QpmP$yvAsHuH{)^I;<)#Kin^Un{8OSdx6xe&59XNMlQc=Ua$lfSmk$|&3$g<-^@2N3Bl5eY#;Ns&%LQaYp&kZzC= z6zOgd47wDQZt3nA6qN3iyn8UuIp4Y8x$Ca)u65Ttf3RjTZ|wc-z2E&jzqrClWmw%H z1QokX{%{jJ{~-yvaO#VZRCs+!Y`V{kR1%*peyb0#rMFOd6B#aiCe8(<>fhXGh;4Rz zko#uIelPJL`{+kfL*RoK!mf26%O6imcEotyg@D-!-}-> z;>hHBSRtJA*JC)C@70oB2XEUr_k^ksV6!nKl}odgtqdX20Ms!P(|gCoIUh~~sWvuf z-ZV_A1)dHvpuW3n?X^(BM2`1_85$aGrGqH6hWRi>fGg1FY3P2Y@6rb)Tl+Qh&3V z_S9OdOlIfmhTOFKUel0NWih4D6U{nSoow@LaEHP%XwBC_I@|1v5M)ijIf@T)W5ZS5 z^#V{bAhPH%UTN>oAeSVMp!Xfj2h)=htw9OgpvDt>Y~6jSW%IMPCxDds?gbkCr^b%p z=~^|u$2miRt?!+(Zd`5G@%heFa7R2V{hIJe z52R&g?H=8w;7_J9>wiXk$7S8f!|m{)d-a#q@B@%FuHw3x=Tq{6XC+5B`$tNG^zUV{ zv*k}I#E$#2W!DEICim{7y(7BpO~}-Bpfvf`sA1D@AMz40{j>sP8*1c0^&qpXv-S2q zKz|>WxvUUeb6OsWRT9B+v}>Gs27F(FI@tgW;m)MB+2;G*vBZN#&p1%!sl!4Y>0HcD z_54sr__G4Jy~nlrGsnvgQeeOV*WzkPBmw!YFD}&Djm5ULaX=jb>}B_|ffIRA9hiDX6$;w}60mX%o1qZJ@bzW^Cr zsQx+1hZm*W+@SxXXfKeARpzV?gr3BJLLCp_b*W=BB}3(Z)%;B$=yI<>7xswJ95xyz z?k!MW&I8`cCkHO~@ArW{kIEu3upAre1zEMl1;9<&we{Qw;(jV)$}guv8@cFlU48)b zp1+_w1zNbnGNywVB$DxGrQyoB;G`Gm9=od$zM{0~0u3?7_47-L?3z^>M2w6^1zVMK|~@vT6$_LbH;8g58uIxg8HYLCcQPxa5%cZ2V7qVzvZGP+@xl zTLZ337{oMCfElR7`f?1kG_)}VawC(KHBFnpuu~(j$-k@V<^|{k4qcysuuO-Rqn!vw36Q4`r0}i#m9@& z_Oi3P(J%?ZT60+ljpGjoFL>($bh~-jM}p`|y!#i7?205VfK%`lofWn{6Lwt1ch#8@ z6duZ%DH|wb{Rg9c&il0cx`@vQtRG@GIV_R4PCWh%S(W(pfwQAdh@Y_q2?`6xBnO`7 zo#*ea;`~MH*4Mo>DC_7=UlRkUga5_P>xul{455P4gZMWeJJXrfGl@rz+}|GnU=_ub z@T~yi+I3naK6BlTLhiepORtTB@NFe2gmFSb{>WJaw`*7*)3)uwwL+Nd{dQdr!<+*M z87Ol6dg@^NpKT!oxml>ieedrh%%=SW`uZL_H?sakCDXJ5Isx(sw(m|N{exqsK|T0| z>z%3~)cYgZEeg3A_6si@YBkaY|MLVGl|U;SdCbRREKwTt!9;n75$wx};;U%Mo zWh7sd18d&K0TOHsVD=$Zi)$*A|7m02bHYl8g)r#l%Ye0|bt1y8{24V6oChfdqe}|X z#Zp)9KlI5X4Rivy&W}J8C>vO`96@(5{%JvfD7$_w@SJ{O15++v5@ECeG$VGdQp^SU}G(4tVRPgS4(QQr8HW; zIsA#BtZ)=23ESyUL@OF-_aSFDph&EF;W}WCIaF37Ne(EHplJt2))93a@$9-$AkB#s zwqaDx5})FRd!6E^{{dMW+(eZ>2?`351w=Qbk`0jMp#eb5iom%K$mZ3<~0s~Kou&rf~{7fa$`L<0Xmx9E#vLx;2*4z~?ZK(?4y!5Jc~mvbsA*#?~LjSw9jf zUtat`lml3ErD-?zU*UdVk6+Z0^+}APe;6I$|9>(%T6wHYgMas{FLdf+;DL7-gre&| zeDP-fU#I#1@zMe~DRW6Y+`olw!Pr^<#VV<^W!BT(+WbNf7*~E%K8N>7xxuW{j12)1 z8hL0xC;Jq-#qfBFzdwp)pQHb2Djp+hC&t)x-A|^BW?%kIX#{SK6siHLwxkTCRtyEr zIZ7PEniy?W-!liDlaj%J61D1x7#TH~s8|#B=8Ik*4`%%?-Q<=9fu&CuL8B)q6LYP$ zK;{qGB<9bU%_?a0*f!w4 zo=<9DDYsHE>GF|m7MB1pG)P2IC~Zm^Fl@Rpj)}GHcMKWeHqg~YBpV_NC*v93z8Sjy zND-?&Ll`D%lQPfDxy0S6b1X<@G4NPdLkFyadBlCZJZcW`G6F_kdo)ui57w%_bxZfN zNYQeFpPQfO>b_KhQx|)$`}KwKW6HA>Z)^U(^G^_A9TSTbTmu^l*So*=YA>uO-Cz9N ztK|OY|4$OD|NnZAP;X2NCm}h!24+yq0oRYQfRxEE1497n^w|INH~dXa7=@~B4s-97q z&O^}@X#{A}m7x6Od&i@PGd`fcffU-m{p9;CKm(Z@s0E+ zC_bv<0-*UAQOmZo&>ekzupw7C^$|##vwsHCd_bMyLlnS9ay+3Fsu1l0G!~f|w*w)C z12A)&w11_}QGGYCz3R{#2yo|l8sF;u&@3YWSU>L4&O)b0cT&g}6}FN?sreU(+u4s* zm3&uwCENZL$#4qVAKP`;P>EP2muuhXhQ@y2$h=hP+4F-s3pz= zy+E=xkbam4X!lqE7?T69eBZu_1u_6)WE@%=zjrk#^1F)J8Rr}!;RXP%G5_+(x2zQ0 za*>pl+DAL4-H5!RnycUVNl`JzWPXLBqTY;P=g-8!*9*9Jy@<~_8`2W+K*XHo-C%Zq ze0_I{u0k2lFfx1QlqN#_o|+e@ng zY;R7^u{kpAYR=j%N_1Hrv+B%sgwJ^_`Dl?<^&u52VIe9S+t(T*f-I37=|q*;AoQCK z0PLG6?3HxOa!P!Ap||KbA3e1$U9QzHx63r?j#GGv5e$2I z(2DcpV1z9-RZ8&C5vNCN7H~2Mp6tAC4YAt74kj#?jT8LXiZvt6F%Wi(PWKvdv(J|k zH?11WST0Gb$RLnuZFwF`$&vILF=MnR3fMn(VMVsU-Y~meAc{|4xNX$@#oNI}mnbGV zCSY?gfavoU+nDOF>%ZF1%wK`Ai)W5!j%EG|2Dm4LyY!OD_fpK$5#9pI9kCt{^xXE; z)?7kouR}wHKL-=q^ez^KmXq3ucm-h}Q3#@WnFE*Lc|cU@oZzv#CB&lgI^yyHwe&AM zy|*?ZVRKC4cS1<6>rX-miH#*G=YFje{X91Bvm8fFHo6eDDYk2`;Bh{(prG~1Bm}pW zlikp_vA((9WwDR;w&SdC_3+!sGu(T-BL(nx8g+h1YkJ^UN!u&DlaG5s5^(c@^K!ht zV??#v+-oFL=nBBp@T?n_BXDZ+(5yOCS#p5Gr&6#VNZ|I7ZZyjfbe?(~3`;*g+@G{W z0YVD8z>Av=C|<;q@mRGd4d($P*QO{oD_)kf<-90vGey#)Jq>`>y8{?Jv3h9q?&AYF z1LbZGJdMoqBph1low;tml2|`;*^4N75syLIO+_Ouz?_@{Z$>OcZdz?s)!4?ptej@*Ng{tH)itOd?%R z{Rfq9_D^E%I+T;7QNs(6osif_9&aon_WZI#OIO7N8ZZOICB3I2&*IeNe$zqAlx9KN8JdTxANLt(hZYCVMew8i#e^~=mPNOl>>gkx2U?P#9+W=_im9? zl0lyUmLJQx3tMC8Y^ML^M}U?wP~d@=YJ;Z)b6nny#69DFt?;12f8bHa;*C=mhwpC> zSsvym6v}s{3P=gBP%LW7+~f+}UHF_R_ZV@eaaOZegn2!C1>7{m<<&^RJNR=;X$3rS7Dka@+V56x}(p zStiO{-*;GK$Sr?eA(2b#7$UFfx%Z7&<(0Zko4AxKD@3!q*$WhdhKBjd8>p|c#q6&M zNJnMMIAuX>t`zzs!6BJ0V()FW0eADsw{0Set%l1JBQ!m|smHniePK0utLfXd??Zau zn@2HzGZ2jbLtlqlH$=?5w*quWPwAKarrp|$N}PqsJXY&t@-6`BHeO~GPqvwG`rKRs zrB%qZ1zv1nclzl)!Pxs`+#^n%o0Y~NtQ&!oJy`1iPgY{jBcDPrU8pL?YwjiIP>Exm z@v(F2rDt0wqX-|F_m({K-P_;PXgs-ht$u7a?O#`&eZuMSU7qO57%bR>7D~qVILm_; zZZIo=g}NXF;luGG^>2b}770&kJ$E?!D2VHFOCnAu0pP z6OHqiTd|sM*e9 zyfhY*73NFGtSAlUpJB$8aFO#N1w_zFEb(xB1(1UW3$8#QiaMpw*%I?@*IC~}2EC8& zYTNTYuh4k|d<_lg6%wGDl?Hy*ljZNomJiPpfG_r3xQH?zUAfZkgP@gO0A|SHRd3l| zi044ZaXeW|5iyoPIjt9oXKz2=@R=Qx@+A@~|G3O!xyV*`x}R)~s8#snyi$0IK5=Ve zbqEmU+`AtFAR=mwqK4pu>^>ru-PkdoW}v|!_Iqa6I=)C5TgG3oeNd<;`ugstO7NYW zm~|)6l5&{>8!Lz-DFqsX=j=;A+#vU87ep*lZv%H7ajrTF7*)j{z`v-}E!uH?U@t^# z8NaDkx$Ys!rljju4&;u%88jbd_9ID3NprfO1m+KCz&cZ{3}zHV(TQ;By8g5mV5rmV za2lWc=E3i$1FGeGqFI_6F%vxyp;s~EN<|B(=UG*jPJOujy>nyimY_?IHIE>WI9{m~ zl#4TS{6NUcx>I+q*Mg(2_OQZcWixU=>-qLo5qglQw|N8XTW2PQ^M<<7*UX1Ih@P;{ zk30xO+5ZZ}bWhs=9lM-6AEo+ayA$`z3!-ifJvX)K&?yX5d2^HY6o~;dX$~a2bGT29 zRinf2^tjQQQ!!02@bR72jaQP`qm}*W0$wK}Y{_Y-`MF#lz5kR>O8#Se9#9zvA;zGg z-Hkwxbqa@`^6Z11+}(N>a?Xw~t!U?3tCxJQ)n9MiekA9FPElKaIHLutM^FkMa;BB& z;Q5o*Rsne5$Rn4od9^~7;S!9i+?GA$)+H*wE31~Q?_dfx)3a0nzFkH8T zPaTTn(x6p<>hu`v767SP#(*~~b`&9xy^)s<#%*Dd_3XM%AMnb&9lm#sRL@Qq0A^A6-NS;U z=j0?T22f?xgLlcaw79e=2XrJ%pxXzk4SUf-gR@$m=WW@oF5>?vzSqXd9OwHC?5V~U z4+m$226COqg&55nD@&r76du0BOAc><xE48OdToOH-uVSmm>0PUDw8oSP*N;ZIi7Ne-yG z1}JZPYAOvhTP<#ug!LQzh~IO31An+(*Q7nebwB zpH@ARp-0v*Ns*AmeIRXMk=%TIX%-UvDcm0`)YrSioN$rcuKsS(j2A_osrice&f$PZXsr0Qu+Mn z)`$;kW=ynkBu2!3pK*ua2f%_v9aX#1?u+ybRQ)A=gY3E88LyF%5UY#V33 z*JFo*B=`7*%k3hw+{t8IIapr2)G>OHRzv!>B&ot}$F!)~mt&73VH^Q!>piV=l{0|B zoX#ILy8OvER)FGl1cL>^JH1!0jeC8Edmo)3_v^@K&F;LBytqmo|LAkM8rRzgLNcje zx3Cn`uRgUsVHJ{Mi(+TX1$e#z38s&6I#yTFTt`B{6vxj(D2~*Q{i)ua|WH)(MG9Y$6Ud!>rBuR}1y7 zKiJW@sd283X5sF%>*zF)iQRPeH$A8HjCwsR#vZjR7AkC2JvY$f7&)H?gX&ktV=2Gm z0nxQfbf5~%0LOqRgC>Z-%!tm z`jp)Fms!CsE%ZG_!qz6n9|lhZ1QT^coFG^T+O?=pm-Q$Xf3=z!rPswJ>Aqv!TQ%&} z&x6roG^&cH`v_T4|EVQLHUvHV!!@Ab0)QLU7#07rdBR$o`n_Ty9dcla%8?sgS1NFE z6)^wBImTiTY550#LnD z`LL=8QA@O7DIzY4x#|TB#;sxTd^6X~WVAlL80vEWXfvs9G5I?7ji~KSS7hndW2RT zB4&QcLH2Ztlz~V8+P;Z0NR67pP^(Kmn1!#GT8|S*F>Nn&au~NMMF3Fko!TZ#(ZPe6 z$c^u85kRzNj2&t!pZ@x>9Nq%*G zrZrIe<{VaW`pkwA6o|ferJA+Pr5%NSZNZewQ@1gSIgZs5s~=mm9O+Ck@`u}bXC^SS zqDr>h0?e_Ip!tTTZURWH4#!8j*}D?6j9-<+XtLX9f>L^oio+k9DF>l1=bU; z0{S2~`ZBv;dV3<60nQq!DclZC7d1)^&JIeANA=oVST*t^>g$yrHMMp}-85!uJ4jHb z?yE}&o;UJbW*s-!X3j-{0?%=P6+EE%u*7)&z@bhK(CRy+(mk(#>(uCTT^=o90}0%i zqS~`o{Gu;(Wsg>Hftp*+EsK*6CLJ*{K{(V)mEVCD&a&jrppplpMO3y*sj9`&!27&x znP^`5qgt}Jii|^2#UBysrZxv{MQDD)@4#qw;t)!m;#JbMs-{cSi`vh$t3qHJS8 z2iL!QUPLpV_dr_kg0%yTWP}qBPQ}{e zInpz%nL?@GIPFdBS%JinAsgBdBmIf@em*wocHk=FpsYDOT~s#a#ydCesX{@8ra$By zivLK?Nh6whUjGj}$NT7qZ`(K0nLt4N1secCMCe(I#tP%M#%om!jM}TKqPnjn*-}q9 z|4@vsmWMl949aw>7rZ~`d|Efuxf$T=P$P~Q&oBf|eD<&A+mpi!?=| zR&fgR?H&+MHSC1{NR0)HkMG&tQp3|bS~bo!NHqlqOtg)9zf+YrkA*_W54NIu|5wbO zA%l~QN37Etoc}vsPx|nG;`Ko9aeJQ}Lg?{(6y2C5*SaUzpc zZt)n#{Wl0%31)tdqs_NjX?GT-#U2Eho}A|ty7 zbFyHN6b^~U#(r!46dy-z+dn5%F>fY%DQ$_ZJH{suYtd2kWQJPa~IV_vV<@D(a$Jz5%qBOYq;HRAW zfzY2ZTfY0ouf3jysbqhSmcr2cv>WcYx|!MY)~NngV}2sHqontbZ8fAY(VkUTJy-); zXrZB`dt!lDoqSD_{L2vRTgJ{ujX!n(y-*_YaLoiM?o_W->-cVzCk&`oEeaKip|GOs z`v{4T6i(6rGpIo;Tx#JPFUfggJ|eo~fr*K%!GhAa`m@tg>z3;c8DV`@8cMevH+^sD zeLBIY271nQDS|A(%xGj+BUe?cKL76No$a-37Wc*|TEI=Z|M3ZtRP}o+_4tKS(_w{Y zu(a2g(bvO(cGBg5C}vc24WQXD@MdEntdpG2UG8a-UTkdM=p9}kyx$}uE{N&)O)KoV z3A>8BAHzs)%JXfJAsVE8w>T}fRY}K0q>-h%P%@#B=gy@wm=K2swJCTwtR_#!eZcwMv^VJ; z9iZi9W9_0td?go9i(ssQyN60-BtH@UzU9DxP%$rjDpQhaeLzSX5Gu4&v>RghSlV# z?4m%;By!q=nmiZ==Ottgjh<@@YX`Ks`I*yW%h^v{%O~T^pUB{RiWEdD_-jP=1yyP5 z_@b2Jx(Rn|f~vPW@^JmJ@`!qX`cm^u+{@$-`~fuVg=(*oz;b;p-E%@~2c;o|2)rIm z0gX5JAO2CkVeBvdkwl@`ERd?n0o6i7-mFhngZQV9fpFxJHQ3qf z7sW@8)1$=K{ANID>(dMj^QH-;W*W48S#A%UIP4X}9rT7MzkZ8Xr3fHaFVvaabm8+3 zmxjrw?G}WR^GQzoC)G}hV-m5`Av1{DfFC%!4b{j-yBsd)+`GvsWGoqerK{s$`Sc^% z`&LUy@nKFb^wFVr(ZjA1^{WQ2Bym8te0iA}Ti-n9{H-#58XVHvt~^tTm%s+CH=nB9 z)L=*%blK_^c?8M@rQXvIol=3!K&a=wR>r+PK)5NEf;1X0tfx0#LH$KTvI2CQzci!> zVxiB`ND)1$3V3jsJE<1!Y_-c}R!AXan0O^85AOP~CL7L~lXzsq@Do#Ai;MWvxEH0& zHwmb%KTd)~cuSwZEZ$k@9qfL&IVe@1e@(}Jmfh&E-DPD$0t^S$gqN*gs3+(KZXC&7 z!VIEKy|@0f?`^T~U69Hz`xGE|lZ`k}PaRNDJSNjVYz}LBYe9oa85=RzTa0 z@*NRsWuGecH4fcRjt^X}t=_x#uv{}h3`O{ee5Al3ALg1wwJLH=?NjLPX?1!VPp>wu zuNv0sc>QwF7j*E|hU4o=Cy5NesBlcbgl(CREAf48z!VE8*fVtkZ}|5Vv!&lDz}svN zyH;W2CU6hn+FdCc^1|^jx*skCfWXgDCj6BT@GBZDRz6UEx;w1~yYaA66y&5BtDMj0 zHOIFrMVmhM0kT|tfUoY}fHm#xi(lcX0u#@1Iy$fU)qr}K|3UbV#B9WPCx2&&SMKWh zH6eG$Xocj8JBk_@8$%hl%gow|^|1-M3dzmZ$jjz}M0j)_bi}gdkcU?}ANMk@0yQs7 z)!SGRE(nYKMl^JCMJ%rUWRyCfQCRj2_f&Soc5I#>^>VVx)_Xjr??zK2I0XPNVIbDTZ<}OEYXwJWt6L7X3eZsj<;~Ir-tn}Fz)xVsI9ChzY z>)uM~Vq4qBEKsd~XUuT4u4Fjbm(6dy zX{atFuou3*&%+3NFNNnNmxK^5*q|%K>QQpU0<}yIEt1Ia=6%&)>1?R{tE+iA} z6;W?}ZeU3RH++WOsb?X(5Gt$f_iDC&{6yag|}(1+lGn9 zqn8)fp8Fay)Th3dPb`Jpb8C;H9?r3x+)uq;Y8Q3Cds)pX)@YMhe_4;fx?_ECVTU

s2>bY3A5dvoLk6-#h5wurXs*w5PrC@c6W7ukgLqNNMup+LmF9ld?JM zwIrU$Xgs_Gk4dXf@d2YR7+dj%`}RBKCGtq_J3PUCnH<9UCaG19W$Fc!0fRB9MIi?- z?nDNNnvOHRv3g(i{^hi@wv>xC`v*6EF&g|eu2&EIJ=aQger&J9W-eg~zkjVz6anYY z*GsDAYxD4I$4a9DSA3k_kEQh+Cu5>PR^E(CWCzEzO^;#Xb73a28=UyR~szDvkI!LIo zd~i$daGnmu5m9&2?S;=S5-4p2_OF8W$7X4rmvR(vv(oxqp!`HZoRmhRSVT8WaLDuw zT=tfo`bd9xUJ$biJuhKhDR$rMwKrQi_U0M)xc`<2bt9YXyol99EaSnOo(~2MkP6HD zuN_HUz6PI<`rV6thEw=vxM1zj?M*bzlWK*7v)7-Q9`9R-vqC?IAG(N1lm~-LLJT9&a|`O<{I^$#$)KODF>~iPPo6Xsl3$ukklf$Qr$>_hZDO$dJf{2O z@UD3OkZ%i))CfF9dmKaYmt<*Xsdrq2R(JYd)hEI$LMgc?`0bkn+y_}zGrAl5uOyW% zS0VcMGUm8%e~6wF;FbkaqdnXE(!1LdgSa8CO4a&9TX2Y0yRvg)?C##G2|avci;>$i zOWZ823!4F&Rb1F*zNv|UYU>=ExaflLLLAo1ONNk6`JqwU8_{09*{f{O9i@Fpwwcv? z^;5JXzkRDfh46@&Z*fYM$D6TOwuhR%RVo839W&3^v@1+C55PqDQL8#%K18oJ--NK! ztnFALbvnRzl`C%KO?9b&->+wPCujT{t#M*BQ`bxFqi_ z|H$VxXP+O4f^aZ!YCR^fSNxLa9wbFG!?C=|1Z{kknIXWB5o**Y-5~~ziV>}Di|^VDA)xf);*Nj^H-6%J)xZeNGAEg)gUHB&Q(I#A zG4Nm$X+w=fX=di+Ob^9x*270{L?t!^66-CF+3|3 z7IYNTZRa~>`gP~&%+wmo%BEB=TAxc$Wj^Pig+GrtV~31C69wHt02yynS0%&`{(UEO z1rDbA>0Q|9*d()I2E71lb9CT;=%a7%D;)vfEXnOMx5M!3T5okvgPBnNe3sHen>`c! z&z6uaDt)dd<_^oC%rtNY2B_Hk$LK!2q3H4O;4DMO7cd5vpFfBi;#9T1Xo`#2YeBiE zQzmVSP5@C(kTktj86bKE=asfNjSNQfu>|n+%nr&ldLfDpYyLU6pp$$}lK9zLxBkbi zb(devR|q;mKWi+O*gs1Ev0p3e(18*>|Jeo@!&BEoVJ6pq1;nH4#n-6fkWWBR{(svW zTmlU@>sLy_y=MlXFh5-$q7jj6zj$7?165(Vh(qYt)2ukSv?uv}3<(-N=vSdylOUxl z9K0nRe2JveFmc067k8t4EA%nG9|I$NgZO=bXcSq{b2iA$-;qRO5Nvg|y^Dr|HbV%a zRZPd}I2K$F_9J(R^CU@XAt?_(8TX^rH9bb{Q86_ii(MXoU3v*@O3@_(c_I_Q&z$` zra2$k7op0J4@dp=f%*G-W>L^VRa8_4fX~)fdC0T$fSrxgV}K4_KL9Tg*iF`@>rt8{ z);G34-+{Q7{=Iy25cui*RR|E!;t}(i!q5Ep>2&hc$I{aBVTn=86t&&a zX`rt<)Mzj>=AWBqz(U3F1HYcQK_Q_O-7kfzQ1SP{1R&cX4A62Znn@=sHEAdqjz2$Q zgb{G$0h?BG4E%d1CIS$Gi(|Y{J5TISBhbNz|W|(@f(3Jk4k4>4!uF zzncQ?*9T>|IK&PJb!q=L=6Kkz(|lMN$&L7X*#IUQTI2!$l)i}hw@E)c|2j>nZiRZ_ zKbO6Qih(@*`cB0){yb~2=m+|rr-@km^!_@--^*rVNW+jvz&i6MvA=ClO8M(F)}sY# zw0|!PQ$Th(O&f+E(6)RCq?_3^3Ux9)f(!rjHQdiynud+7TfN}nBS3y`4|m5n%z&Pd#l58y{63JQxJ3p5M>xX6sQ89L~>9*O`g8&QDeWMDB3D zbhbnD)<_bMRX(W4suvqH+<5Cp#q#&=wUi7%#_NN{AQLOlof#o!!jgkyA-M98^VX#w z!0>D=O~@l3)S#883bg-eq#qd8W5o>sTx$!27M0FAC?s(hpijo0qkL%06$N0fC)Hcj zl6CzBe|lL))>o!~ZL(tFa2O>C)DA9RxDAbidd37;2`fo@Ci@IKPeq-4cUB1IN{w0|AJqwl4yYf}c~+Qp-_|i%f(vF@Kc@r51YOPkVW;5`Spqkn!cP9qD($^<<;XK9i5Z}`Cd zOfJGXqH8~|^iMN^Fcp`%h%4E_ew#mS4*qDDzxX@nd#my|ZW z82jzkb=Rx@d4AEDi=N23MLEs%&m|+eF20T$_f~WMd)sioYZs$U+~UqBg?}%Zc=0tu z*=g=7cxZbXPWN5&s@(y(HK0x{{IixFt@z|L?o4iZ@J+bW`qU2^dzzWSnCnka71$e zQ<4oxW$u5b4FEKYmHP>}bOC_q9XDcejQOIXQM8^OA4~!)cWRUKpaP#nAa4Tv^Xi#c z6_v}Bz4MT=l!RKmC|}DbD$q{mm>VKJfa)fYWS#Y?Exjs0)GoBd-9;8AZd!<3bRxC7 zd^CW=cmM4!x9$0x6z<;cEIPEsmc!Q%vT(jTN~u+zKmK~jw~X(}yfm1I>S?uX!2Cw# zeQ0>l$o%E=+5V)h^J+;Ox|cO*iG1|3rgt9s>wy@Gvv?vW2EY{EQPEIx3D7Bc0!Dd8 zbqMpMo^>(n(9Y`b1KB*%eQmJ9M)blQ?+R{Xt0i>7A@q`=#h?|Z!FG&d0sBpMcI7aK z=A#87R3F++AQUej&}Hr#tj3?7hw8NJkvoO2@3n zGzeO2z%OZ)cL3oCN+e!|p#kWpAa2>i0g`k$OmJJ8uj+GGiVvnUWzXlDgPD~yP+@$$ zkmC9^h`7_@P3m{k75gboLqAHEF@)WOzQ-C5z#3%|8Ud+z=krM6lg)d_pviEaB@$7q zTf@@7BEX7Nan~Q6QuPFocdJ~@^>RT~sdU;Qqjz(YrH?utnFG`kxO@1U z;yCozmmT^gh{wTLP938O*M9u5#d7E^ekpG4{yky92YTX0bM&y>{7YIxSDnvz-O)0u zhSUUnl9b=hz}?G0v(DSg3V`ldwQspak)o~4w@2&Ngx&s5qVWc4s4}_)P-8qPN~_VO zMn#z_*J$BgfX>8GdzeKi3Z(QL_d2C1M0UEkdq!&R3wH$L^aTL|9R7JTp;BcmY+3dk zC>?&pe|k5ygm9k#Xb%jivG(nh5b}Hd_!i%TYp+huYrVMMAUvy-XefOy@HLoz3Nhn- zY?CbDQn+Fjd=;@tu72xK`%7b>ZZK6Si(K&&;LxLr?+ zERDIOry>#X&u{BEM~dkhG||eeifVXk@D3*>XyWFz0jZ!u?6{5Er?OOVvmR|9Op5}_ z_dN8ye|#%U=YFli+{!qCaZSrR3`3@C~mkRvz@ji&t zDh&J?h0rF>=AJR`dp{V+hOGnwK8pSL%Kl+W0aub{DPGd}01Js;^>_5TW9`T0qn3Y z08SuCErs)pz$}oH?tDeh=hW!{0^r}1(=Q;G-)WVZK8DX-dhXx!;`9YaEvG3Yk#Sq8 zp%9A^3OA~@c6;}Lm_l2eh$B_h$Df?T*{IgA!wWkXJA=QS|I$>iTzLGwY*xrruh4w& z3%>@Ek?K_oV+w*srOKeXY0sVR9={_n6<7nASH;7Kr^5}S-f*4(U?*?}24Er1Tf)`T z&UIF(=cFN!RxJz_BvdA`Nvpnpt*(u5q&fz8cCMsgY`3{dlq;*J*iuB_XNiHsOzy$> zJLdLC16bCcqb;Tb8OSe{C8Q)~jeOYc`mp-vXTH&4x^tZUwoBYGNd3acp|E|=3G&N9 zpT6W9Rn6c10TBGc3((ER1HH|1jK=EL-es;taH!D8Z{J+{l6FCVtJ@6fCHS#%0PP@LigF|-9Zce3GSfv9Iu3?@DZD zeq#Y_CWdhA&N6wsHo2rZcZfJ>>*X=S(8*sI zk2+#l9;4iaZK{}!j3hJeU7}w7bRW3E?~tPL;8JjNoptur`n>AG&WMR_e$hk74MWvC z0ku|X4x?-_-*{|AA~b%CurBDxy9aGJ^IabZuC`iZ`U~#|-1}M=N}Z2e>)eVJ;k<1P zH|3A1zSamLM%jgxFea7=png~zxkTydua+pg)*ih30jrBK<%29?hC-FHD;$z^jBwqF{faN69L ze8d3tY@0NYepkO@L>-H1Gp0#uavzw|Qepd&c{cb+ij6FT4<* zfq;^w*W9e1i;IMBBBaTz1x>6?qFTuD#-)2ZXpQe!GzMTimYmU6-m@t($h=#dR~0#Q znYO-inNqT$Dk}DtQm{dISM#6<Eqg~J!zE*L5QtC|2q~&~a{qxVvyli) zDBzh{Q>aF{h#1Y-F)%hcoXFXzN~=})QB4Fv>l4PE{ja>vIs zwHMQ9bC259>5H9w$_>U!(RC?&wmRW>v4nWDo zv!*be-6ALp=U3_~KLo_kv8{9$f&g1Ld%XnZxl3Vi1E&Tok1b?uNe7^mbxj zo%5kf*^Weyv+%0V-Dnkq&8{A|BHTF?t(!GqheZ>dF%CQ-=guLrKl&j=U*j*4&& zA3fo68GbPoGn4)-iNZ5IdDn8cM!YsZJ5&xsxvu&h$U#B0h7Sdy&*j!S;~)ZvpEXPh zec{sOMDeQ48;FQ&8wdOhGcPFa*2@(FIRo~5_5}E*nY=U!?j>5c%rra>(=|IuO~&mM z{Rw!aZ?xj!rN&r0sC5XbNE(L71V(>|@jSV=SgL2BXz`OxZ0j&Jq3xE)jPN;%$fx7n zkSH_y;zgw)zbl3CdYSLzwX`n4j>n-V?mXmPrlxxyK`6K0?Q3%2)g+XKd}xWdmX#sR zCTL=%Uh^}FA|<}P-e=7HhU=`~T0+E4W@CbYo$yQ1xw7-1MY{kLFV;TSMGol6N*5-1 zPa!dcs1Uxnb{y*QWuy&sa0MIp98ABp#K6sHr)$V~B|zDTdxix6ty1YxuPlmJSjp2n zG*9tiC%d}iyF`$NBPC8+-P(&_$ zF}d04+p(`u{Wfurp+y_E88zS1BA;_kv$lrMKh;OG+}0URii>#JH`IInNWv?Ta@%y& z>oU$A5)KS8)r9vn)~IiK&#$~P7~P_4#b|ohZ65Bs@f-zBMW zicC!yYRabQF)gkX>~I8xK|&(kcjB$!o$tq?_r-iSdC{Hu2h{bR^D3Pap;Fi$p|360 z(ZNID2JO_z2dkl;Zur|@+jt@4aPCU}2|*FftQ+|~@FTx5M%t^z%qbtu15xPs`*!RH z;FAGcaIqlnRZ8WK&Xf%jn)*ZqQ}l>CG!qG43pwF)Usp&1AL7GQaS=igJA>9Yvf0%JmSxeyQPhkGTYmruNtDk~>Y;8BUuVR>d&YE=;|;CHV7D`NEJC+%9gCv}UyO#4k+IvO zWNVwDe@ps=d?7CVjN3$OjGa{Y4nEn7cx-N(YE412xWs!Y_(o2NB`==A4KlV⋘l1 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 Date: Tue, 30 May 2023 23:00:23 +0300 Subject: [PATCH 101/207] upgraded version for azure-servicebus sdk --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a8c06268fd..34f8f77de1 100755 --- a/pom.xml +++ b/pom.xml @@ -111,7 +111,7 @@ 1.11.747 1.105.0 2.1.0 - 3.2.0 + 3.6.7 1.5.0 1.5.4 1.9.4 From 24b82939c3e84fb152911e571ea77f8bcdf43a94 Mon Sep 17 00:00:00 2001 From: imbeacon Date: Thu, 1 Jun 2023 10:12:08 +0300 Subject: [PATCH 102/207] Fixes for models in Swagger --- .../org/thingsboard/server/common/data/id/NotificationId.java | 2 ++ .../server/common/data/id/NotificationRequestId.java | 2 ++ .../thingsboard/server/common/data/id/NotificationRuleId.java | 2 ++ .../thingsboard/server/common/data/id/NotificationTargetId.java | 2 ++ .../server/common/data/id/NotificationTemplateId.java | 2 ++ .../java/org/thingsboard/server/common/data/id/QueueId.java | 2 ++ 6 files changed, 12 insertions(+) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationId.java index 7b11e86c9f..37934e1f50 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationId.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -28,6 +29,7 @@ public class NotificationId extends UUIDBased implements EntityId { super(id); } + @ApiModelProperty(position = 2, required = true, value = "string", example = "NOTIFICATION", allowableValues = "NOTIFICATION") @Override public EntityType getEntityType() { return EntityType.NOTIFICATION; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationRequestId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationRequestId.java index 3696aa0582..c7a65f49d2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationRequestId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationRequestId.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -28,6 +29,7 @@ public class NotificationRequestId extends UUIDBased implements EntityId { super(id); } + @ApiModelProperty(position = 2, required = true, value = "string", example = "NOTIFICATION_REQUEST", allowableValues = "NOTIFICATION_REQUEST") @Override public EntityType getEntityType() { return EntityType.NOTIFICATION_REQUEST; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationRuleId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationRuleId.java index d9294b7fba..988b92600a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationRuleId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationRuleId.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -28,6 +29,7 @@ public class NotificationRuleId extends UUIDBased implements EntityId { super(id); } + @ApiModelProperty(position = 2, required = true, value = "string", example = "NOTIFICATION_RULE", allowableValues = "NOTIFICATION_RULE") @Override public EntityType getEntityType() { return EntityType.NOTIFICATION_RULE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationTargetId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationTargetId.java index 85d26ffde0..435da5e3c2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationTargetId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationTargetId.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -28,6 +29,7 @@ public class NotificationTargetId extends UUIDBased implements EntityId { super(id); } + @ApiModelProperty(position = 2, required = true, value = "string", example = "NOTIFICATION_TARGET", allowableValues = "NOTIFICATION_TARGET") @Override public EntityType getEntityType() { return EntityType.NOTIFICATION_TARGET; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationTemplateId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationTemplateId.java index 6570d76c57..7e0119c7f8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationTemplateId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/NotificationTemplateId.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -28,6 +29,7 @@ public class NotificationTemplateId extends UUIDBased implements EntityId { super(id); } + @ApiModelProperty(position = 2, required = true, value = "string", example = "NOTIFICATION_TEMPLATE", allowableValues = "NOTIFICATION_TEMPLATE") @Override public EntityType getEntityType() { return EntityType.NOTIFICATION_TEMPLATE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/QueueId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/QueueId.java index 4ebc531c4b..866f50f5d9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/QueueId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/QueueId.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -34,6 +35,7 @@ public class QueueId extends UUIDBased implements EntityId { return new QueueId(UUID.fromString(queueId)); } + @ApiModelProperty(position = 2, required = true, value = "string", example = "QUEUE", allowableValues = "QUEUE") @Override public EntityType getEntityType() { return EntityType.QUEUE; From cf3c863973fc0d88623ea5b28fdbe6fb0cb7d2a6 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 1 Jun 2023 12:11:31 +0300 Subject: [PATCH 103/207] added field templatization docs for enrichment rule nodes --- ...r_attributes_node_fields_templatization.md | 118 +++---- ...r_attributes_node_fields_templatization.md | 132 ++++++++ ...nator_fields_node_fields_templatization.md | 106 +++++++ ...or_telemetry_node_fields_templatization.md | 292 ++++++++++++++++++ ...e_attributes_node_fields_templatization.md | 132 ++++++++ ..._entity_data_node_fields_templatization.md | 111 +++++++ ...t_attributes_node_fields_templatization.md | 107 +++++++ .../examples/originator-attributes-ft.png | Bin 0 -> 73529 bytes .../examples/originator-fields-ft.png | Bin 0 -> 70946 bytes .../examples/originator-telemetry-ft-2.png | Bin 0 -> 60659 bytes .../examples/originator-telemetry-ft-3.png | Bin 0 -> 78213 bytes .../examples/originator-telemetry-ft.png | Bin 0 -> 69883 bytes .../examples/related-device-attributes-ft.png | Bin 0 -> 60303 bytes .../examples/related-entity-data-ft-2.png | Bin 0 -> 76684 bytes .../examples/related-entity-data-ft.png | Bin 0 -> 59833 bytes .../examples/tenant-attributes-ft.png | Bin 0 -> 82917 bytes 16 files changed, 942 insertions(+), 56 deletions(-) create mode 100644 ui-ngx/src/assets/help/en_US/rulenode/originator_attributes_node_fields_templatization.md create mode 100644 ui-ngx/src/assets/help/en_US/rulenode/originator_fields_node_fields_templatization.md create mode 100644 ui-ngx/src/assets/help/en_US/rulenode/originator_telemetry_node_fields_templatization.md create mode 100644 ui-ngx/src/assets/help/en_US/rulenode/related_device_attributes_node_fields_templatization.md create mode 100644 ui-ngx/src/assets/help/en_US/rulenode/related_entity_data_node_fields_templatization.md create mode 100644 ui-ngx/src/assets/help/en_US/rulenode/tenant_attributes_node_fields_templatization.md create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/originator-attributes-ft.png create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/originator-fields-ft.png create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/originator-telemetry-ft-2.png create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/originator-telemetry-ft-3.png create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/originator-telemetry-ft.png create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/related-device-attributes-ft.png create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/related-entity-data-ft-2.png create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/related-entity-data-ft.png create mode 100644 ui-ngx/src/assets/help/images/rulenode/examples/tenant-attributes-ft.png diff --git a/ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fields_templatization.md index 231ea2a0cb..e01d90faf4 100644 --- a/ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fields_templatization.md +++ b/ui-ngx/src/assets/help/en_US/rulenode/customer_attributes_node_fields_templatization.md @@ -7,89 +7,95 @@ ##### Examples -Let's assume that we have a customer-based solution where customer manage two type of devices: `temperature` and `humidity` sensors. -Additionally, let's assume that customer configured the thresholds settings for each device type. +Let's assume that we have a customer-based solution where customer manage two type of devices: `temperature` and `humidity` sensors. +Additionally, let's assume that customer configured the thresholds settings for each device type. Threshold settings stored as an attributes on a customer level: - - *temperature_min_threshold* and *temperature_max_threshold* for temperature sensor with values set to *10* and *30* accordingly. - - *humidity_min_threshold* and *humidity_max_threshold* for humidity sensor with values set to *70* and *85* accordingly. +- *temperature_min_threshold* and *temperature_max_threshold* for temperature sensor with values set to *10* and *30* accordingly. +- *humidity_min_threshold* and *humidity_max_threshold* for humidity sensor with values set to *70* and *85* accordingly. -Each message received from device includes `deviceType` property in the message metadata +Each message received from device includes `deviceType` property in the message metadata with either `temperature` or `humidity` value according to the sensor type. -In order to fetch the threshold value for the further message processing you can define next mapping in the configuration: +In order to fetch the threshold value for the further message processing you can define next node configuration: ![image](${helpBaseUrl}/help/images/rulenode/examples/customer-attributes-ft.png) -Imagine that you receive message defined below from the `temperature` sensor +Imagine that you receive message defined below from the `temperature` sensor and forwarded it to the **customer attributes** node with configuration added above. - - incoming message definition: +- incoming message definition: ```json - { - "msg":{ - "temperature":32 - }, - "metadata":{ - "deviceType":"temperature", - "deviceName":"TH-001", - "ts":1685379440000 - } - } +{ + "msg": { + "temperature": 32 + }, + "metadata": { + "deviceType": "temperature", + "deviceName": "TH-001", + "ts": "1685379440000" + } +} ``` -Rule node configuration set to fetch data to the message metadata so the outgoing message would be updated to: +
+ +The same example for the `humidity` sensor: + +- incoming message definition: ```json - { - "msg":{ - "temperature":32 - }, - "metadata":{ - "deviceType":"temperature", - "deviceName":"TH-001", - "ts":1685379440000, - "min_threshold":"10", - "max_threshold":"30" - } - } +{ + "msg": { + "humidity": 77 + }, + "metadata": { + "deviceType": "humidity", + "deviceName": "HM-001", + "ts": "1685379440000" + } +} ```
-The same example for the `humidity` sensor: +Rule node configuration set to fetch data to the message metadata. In the following way: -- incoming message definition: +- outgoing message for the `temperature` sensor would be updated to: ```json - { - "msg":{ - "humidity":77 - }, - "metadata":{ - "deviceType":"humidity", - "deviceName":"HM-001", - "ts":1685379440000 - } - } +{ + "msg": { + "temperature": 32 + }, + "metadata": { + "deviceType": "temperature", + "deviceName": "TH-001", + "ts": "1685379440000", + "min_threshold": "10", + "max_threshold": "30" + } +} ``` -Rule node configuration wasn't changed so the outgoing message would be updated to: +
+ +- outgoing message for the `humidity` sensor would be updated to: ```json - { - "msg":{ - "humidity":77 - }, - "metadata":{ - "deviceType":"humidity", - "deviceName":"HM-001", - "ts":1685379440000, - "min_threshold":"70", - "max_threshold":"85" - } - } +{ + "msg": { + "humidity": 77 + }, + "metadata": { + "deviceType": "humidity", + "deviceName": "HM-001", + "ts": "1685379440000", + "min_threshold": "70", + "max_threshold": "85" + } +} ```
diff --git a/ui-ngx/src/assets/help/en_US/rulenode/originator_attributes_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/originator_attributes_node_fields_templatization.md new file mode 100644 index 0000000000..bd9bba3fbd --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/rulenode/originator_attributes_node_fields_templatization.md @@ -0,0 +1,132 @@ +#### Fields templatization + +

+
+ +{% include rulenode/common_node_fields_templatization %} + +##### Examples + +Let's assume that we have a moisture meter device(message originator) that publishes a telemetry messages that includes the following data readings: + +- `soilMoisture` +- `windSpeed` +- `windDirection` +- `temperature` +- `humidity` + +Depending on certain conditions, we might need to fetch additional server-side attributes from the moisture meter device. + +Specifically, if the soil moisture reading drops below a certain threshold, let's say 30%, this is considered critical as it directly impacts crop health and growth. +In this case, we need to fetch the `lastIrrigationTime` attribute. +This additional information can help us understand when the field was last watered and take necessary action, such as activating the irrigation system. +However, if the soil moisture is above this critical threshold, then we need to check another condition. +If the wind speed is above a certain level, say 8 m/s, we need to fetch the `lastWindSpeedAlarmTime` attribute. +This additional information can help us to understand when the last significant wind event occurred, +which might be indicative of an approaching storm or damaging winds. + +Consider that you write a script that depending on a conditions written above will add to the message metadata additional key: `keyToFetch` with one of the next values: + +- `lastIrrigationTime` +- `lastWindSpeedAlarmTime` + +In order to fetch value of one of the following keys for the further message processing you can define next node configuration: + +![image](${helpBaseUrl}/help/images/rulenode/examples/originator-attributes-ft.png) + +- message definition that match first condition after processing in the script node: + +```json +{ + "msg": { + "temperature": 26.5, + "humidity": 75.2, + "soilMoisture": 28.9, + "windSpeed": 8.2, + "windDirection": "NNE" + }, + "metadata": { + "deviceType": "default", + "deviceName": "SN-001", + "ts": "1685379440000", + "keyToFetch": "lastIrrigationTime" + } +} +``` + +
+ +- message definition that match second condition after processing in the script node: + +```json +{ + "msg": { + "temperature": 26.5, + "humidity": 75.2, + "soilMoisture": 32.5, + "windSpeed": 10.4, + "windDirection": "NNE" + }, + "metadata": { + "deviceType": "default", + "deviceName": "SN-001", + "ts": "1685379440000", + "keyToFetch": "lastWindSpeedAlarmTime" + } +} +``` + +
+ +Rule node configuration set to fetch data to the message metadata. In the following way: + +- outgoing message for the first condition would be updated to: + +```json +{ + "msg": { + "temperature": 26.5, + "humidity": 75.2, + "soilMoisture": 28.9, + "windSpeed": 8.2, + "windDirection": "NNE" + }, + "metadata": { + "deviceType": "default", + "deviceName": "SN-001", + "ts": "1685379440000", + "keyToFetch": "lastIrrigationTime", + "ss_lastIrrigationTime": "1685369440000" + } +} +``` + +
+ +- outgoing message for the second condition would be updated to: + +```json +{ + "msg": { + "temperature": 26.5, + "humidity": 75.2, + "soilMoisture": 32.5, + "windSpeed": 10.4, + "windDirection": "NNE" + }, + "metadata": { + "deviceType": "default", + "deviceName": "MM-001", + "ts": "1685379440000", + "keyToFetch": "lastWindSpeedAlarmTime", + "ss_lastWindSpeedAlarmTime": "1685359440000" + } +} +``` + +
+ +These examples showcases using the **originator attributes** node with dynamic configuration based on the substitution of metadata fields. + +
+
diff --git a/ui-ngx/src/assets/help/en_US/rulenode/originator_fields_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/originator_fields_node_fields_templatization.md new file mode 100644 index 0000000000..b21f450ae9 --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/rulenode/originator_fields_node_fields_templatization.md @@ -0,0 +1,106 @@ +#### Fields templatization + +
+
+ +{% include rulenode/common_node_fields_templatization %} + +##### Examples + +Let's assume that we have two device types in our use case: + +- `smart_door_lock` +- `motion_detector` + +Let's assume that device of type `dock_lock_sensor` and name `SDL-001` publish next type of messages to the system: + +```json +{ + "msg": { + "status": "locked" + }, + "metadata": { + "deviceName": "SDL-001", + "deviceType": "smart_door_lock", + "ts": "1685379440000" + } +} +``` + +
+ +and device of type `motion_detector` and name `MD-001` publish next type of messages to the system: + +```json +{ + "msg": { + "motionDetected": "true" + }, + "metadata": { + "deviceName": "MD-001", + "deviceType": "motion_detector", + "ts": "1685379440000" + } +} +``` + +
+ +Imagine that you send the messages received from the devices to the external systems +and depending on the device type you need add to the message the human-readable label +of the device with field name equal to the `deviceType` value from the message metadata. + +Let's assume that devices have next labels: + +- *Grocery warehouse door* for `SDL-001` device. +- *Grocery Warehouse motion detector* for `MD-001` device. + +In order to fetch labels and add them to the message with the appropriate field name +you can define the next node configuration: + +![image](${helpBaseUrl}/help/images/rulenode/examples/originator-fields-ft.png) + +
+ +Rule node configuration set to fetch data to the message. In the following way: + +- outgoing message for the `SDL-001` device would be updated to: + +```json +{ + "msg": { + "status": "locked", + "smart_door_lock": "Grocery warehouse door" + }, + "metadata": { + "deviceName": "SDL-001", + "deviceType": "smart_door_lock", + "ts": "1685379440000" + } +} +``` + +
+ +- outgoing message for the `MD-001` device would be updated to: + +```json +{ + "msg": { + "motionDetected": "true", + "motion_detector": "Grocery Warehouse motion detector" + }, + "metadata": { + "deviceName": "MD-001", + "deviceType": "motion_detector", + "ts": "1685379440000" + } +} +``` + +
+ +These examples showcases using the **originator fields** node with dynamic configuration based on the substitution of metadata fields. + +
+
diff --git a/ui-ngx/src/assets/help/en_US/rulenode/originator_telemetry_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/originator_telemetry_node_fields_templatization.md new file mode 100644 index 0000000000..e433536726 --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/rulenode/originator_telemetry_node_fields_templatization.md @@ -0,0 +1,292 @@ +#### Fields templatization + +
+
+ +{% include rulenode/common_node_fields_templatization %} + +##### Examples + +Originator telemetry node support templatization for multiple configuration fields. Namely, you can specify the template in the +*Timeseries keys* list, and also there is an option to use the templatization for the fetch interval start and end if you are using *dynamic interval*. + +###### Example 1 + +Let's start with an example of using templatization for the *Timeseries keys* list. +Imagine that you have a GPS tracker device(message originator) that publishes a telemetry messages that includes the following data readings: + +- `latitude` - current device latitude value. +- `longitude` - current device longitude value. +- `event` - parameter that specifies the current state of the device. The value might be *parked* or *motion*. + +Additionally let's imagine that devices periodically publishes other telemetry messages that includes additional information such as: + +- `speed` - current speed value. +- `direction` - compass direction in which the device is moving. +- `acceleration` - how quickly the speed of the device is changing. +- `fuel_level` - current fuel level. +- `battery_level` - current battery level. +- `parked_location` - precise location where the device is parked. +- `parked_duration` - current park duration value. +- `parked_time` - timestamp when the device was parked. + +Let's imagine that we need to make some historical analysis by fetching 3 latest telemetry readings for the keys listed below if the `event` value is set to *motion*: + +- `speed` +- `direction` +- `acceleration` +- `fuel_level` +- `battery_level` + +Otherwise, if the `event` value is set to *parked* value we need to fetch 3 latest telemetry readings for the following data keys: + +- `parked_location` +- `parked_duration` +- `parked_time` +- `fuel_level` +- `battery_level` + +Imagine that you created a script node that depending on the `event` value adds to the message metadata appropriate keyToFetch fields. + +- message definition that match condition when `event` is set to *motion* value after processing in the script node: + +```json +{ + "msg": { + "latitude": "40.730610", + "longitude": "-73.935242", + "event": "motion" + }, + "metadata": { + "deviceName": "GPS-001", + "deviceType": "GPS Tracker", + "ts": "1685479440000", + "keyToFetch1": "speed", + "keyToFetch2": "direction", + "keyToFetch3": "acceleration" + } +} +``` + +
+ +- message definition that match condition when `event` is set to *parked* value after processing in the script node: + +```json +{ + "msg": { + "latitude": "40.730610", + "longitude": "-73.935242", + "event": "parked" + }, + "metadata": { + "deviceName": "GPS-001", + "deviceType": "GPS Tracker", + "ts": "1685379440000", + "keyToFetch1": "parked_location", + "keyToFetch2": "parked_duration", + "keyToFetch3": "parked_time" + } +} +``` + +
+ +In order to fetch the additional telemetry key values to make some historical analysis of the tracker's state you can define the next node configuration: + +![image](${helpBaseUrl}/help/images/rulenode/examples/originator-telemetry-ft.png) + +![image](${helpBaseUrl}/help/images/rulenode/examples/originator-telemetry-ft-2.png) + +
+ +Rule node configuration is set to retrieve the telemetry from the fetch interval with configurable query parameters that you can check above. +So let's imagine that 3 latest values for the keys that we are going to fetch are: + +- `speed` - 5.2, 15.7, 30.2 (mph). +- `direction` - N(North), NE(North-East), E(East). +- `acceleration` - 2.2, 2.4, 2.5 (m/s²). +- `fuel_level` - 61.5, 57.4, 55.6 (%). +- `battery_level` - 88.1, 87.8, 87.2 (%). +- `parked_location` - dr5rtwceb (geohash). Same value for 3 latest data readings. +- `parked_duration` - 6300000, 7300000, 8300000 (ms). +- `parked_time` - 1685339240000 (ms). Same value for 3 latest data readings. + +In the following way: + +- outgoing message for the case when the `event` has value *motion* would be look like this: + +```json +{ + "msg": { + "latitude": "40.730610", + "longitude": "-73.935242", + "event": "motion" + }, + "metadata": { + "deviceName": "GPS-001", + "deviceType": "GPS Tracker", + "ts": "1685479440000", + "keyToFetch1": "speed", + "keyToFetch2": "direction", + "keyToFetch3": "acceleration", + "speed": "[{\"ts\":1685476840000,\"value\":5.2},{\"ts\":1685477840000,\"value\":15.7},{\"ts\":1685478840000,\"value\":30.2}]", + "direction": "[{\"ts\":1685476840000,\"value\":\"N\"},{\"ts\":1685477840000,\"value\":\"NE\"},{\"ts\":1685478840000,\"value\":\"N\"}]", + "acceleration": "[{\"ts\":1685476840000,\"value\":2.2},{\"ts\":1685477840000,\"value\":2.4},{\"ts\":1685478840000,\"value\":2.5}]", + "fuel_level": "[{\"ts\":1685476840000,\"value\":61.5},{\"ts\":1685477840000,\"value\":57.4},{\"ts\":1685478840000,\"value\":55.6}]", + "battery_level": "[{\"ts\":1685476840000,\"value\":88.1},{\"ts\":1685477840000,\"value\":87.8},{\"ts\":1685478840000,\"value\":87.2}]" + } +} +``` + +
+ +- outgoing message for the case when the `event` has value *parked* would be look like this: + +```json +{ + "msg": { + "latitude": "40.730610", + "longitude": "-73.935242", + "event": "parked" + }, + "metadata": { + "deviceName": "GPS-001", + "deviceType": "GPS Tracker", + "ts": "1685379440000", + "keyToFetch1": "parked_location", + "keyToFetch2": "parked_duration", + "keyToFetch3": "parked_time", + "parked_location": "[{\"ts\":1685376840000,\"value\":\"dr5rtwceb\"},{\"ts\":1685377840000,\"value\":\"dr5rtwceb\"},{\"ts\":1685378840000,\"value\":\"dr5rtwceb\"}]", + "parked_duration": "[{\"ts\":1685376840000,\"value\":6300000},{\"ts\":1685377840000,\"value\":7300000},{\"ts\":1685378840000,\"value\":8300000}]", + "parked_time": "[{\"ts\":1685376840000,\"value\":1685376840000},{\"ts\":1685377840000,\"value\":1685377840000},{\"ts\":1685378840000,\"value\":1685378840000}]", + "fuel_level": "[{\"ts\":1685376840000,\"value\":61.5},{\"ts\":1685377840000,\"value\":57.4},{\"ts\":1685378840000,\"value\":55.6}]", + "battery_level": "[{\"ts\":1685376840000,\"value\":88.1},{\"ts\":1685377840000,\"value\":87.8},{\"ts\":1685378840000,\"value\":87.2}]" + } +} +``` + +###### Example 2 + +This example will extend the previous example with additional condition: + +Imagine that you need to specify the fetch interval dynamically from the 1 hour ago till the current time. +Additionally let's assume that the current time can be extracted from `ts` field that we have in the message metadata on each message received. +While the value of (1 hour ago) can be calculated in the script node that we use for adding keyToFetch fields into metadata. + +In the following way: + +- message definition that match condition when `event` is set to *motion* value after processing in the script node: + +```json +{ + "msg": { + "latitude": "40.730610", + "longitude": "-73.935242", + "event": "motion" + }, + "metadata": { + "deviceName": "GPS-001", + "deviceType": "GPS Tracker", + "ts": "1685479440000", + "keyToFetch1": "speed", + "keyToFetch2": "direction", + "keyToFetch3": "acceleration", + "dynamicIntervalStart": "1685475840000" + } +} +``` + +- message definition that match condition when `event` is set to *parked* value after processing in the script node: + +```json +{ + "msg": { + "latitude": "40.730610", + "longitude": "-73.935242", + "event": "parked" + }, + "metadata": { + "deviceName": "GPS-001", + "deviceType": "GPS Tracker", + "ts": "1685379440000", + "keyToFetch1": "parked_location", + "keyToFetch2": "parked_duration", + "keyToFetch3": "parked_time", + "dynamicIntervalStart": "1685375840000" + } +} +``` + +
+ +In order to fetch the data using dynamic interval we need enable *Use dynamic interval* option in the rule node configuration and specify the templates for the *Interval start* and *Interval end*: + + +![image](${helpBaseUrl}/help/images/rulenode/examples/originator-telemetry-ft-3.png) + +
+ +Other configuration wasn't change from our previous example. +In the following way: + +- outgoing message for the case when the `event` has value *motion* would be look like this: + +```json +{ + "msg": { + "latitude": "40.730610", + "longitude": "-73.935242", + "event": "motion" + }, + "metadata": { + "deviceName": "GPS-001", + "deviceType": "GPS Tracker", + "ts": "1685479440000", + "keyToFetch1": "speed", + "keyToFetch2": "direction", + "keyToFetch3": "acceleration", + "dynamicIntervalStart": "1685475840000", + "speed": "[{\"ts\":1685476840000,\"value\":5.2},{\"ts\":1685477840000,\"value\":15.7},{\"ts\":1685478840000,\"value\":30.2}]", + "direction": "[{\"ts\":1685476840000,\"value\":\"N\"},{\"ts\":1685477840000,\"value\":\"NE\"},{\"ts\":1685478840000,\"value\":\"N\"}]", + "acceleration": "[{\"ts\":1685476840000,\"value\":2.2},{\"ts\":1685477840000,\"value\":2.4},{\"ts\":1685478840000,\"value\":2.5}]", + "fuel_level": "[{\"ts\":1685476840000,\"value\":61.5},{\"ts\":1685477840000,\"value\":57.4},{\"ts\":1685478840000,\"value\":55.6}]", + "battery_level": "[{\"ts\":1685476840000,\"value\":88.1},{\"ts\":1685477840000,\"value\":87.8},{\"ts\":1685478840000,\"value\":87.2}]" + } +} +``` + +
+ +- outgoing message for the case when the `event` has value *parked* would be look like this: + +```json +{ + "msg": { + "latitude": "40.730610", + "longitude": "-73.935242", + "event": "parked" + }, + "metadata": { + "deviceName": "GPS-001", + "deviceType": "GPS Tracker", + "ts": "1685379440000", + "keyToFetch1": "parked_location", + "keyToFetch2": "parked_duration", + "keyToFetch3": "parked_time", + "dynamicIntervalStart": "1685375840000", + "parked_location": "[{\"ts\":1685376840000,\"value\":\"dr5rtwceb\"},{\"ts\":1685377840000,\"value\":\"dr5rtwceb\"},{\"ts\":1685378840000,\"value\":\"dr5rtwceb\"}]", + "parked_duration": "[{\"ts\":1685376840000,\"value\":6300000},{\"ts\":1685377840000,\"value\":7300000},{\"ts\":1685378840000,\"value\":8300000}]", + "parked_time": "[{\"ts\":1685376840000,\"value\":1685376840000},{\"ts\":1685377840000,\"value\":1685377840000},{\"ts\":1685378840000,\"value\":1685378840000}]", + "fuel_level": "[{\"ts\":1685376840000,\"value\":61.5},{\"ts\":1685377840000,\"value\":57.4},{\"ts\":1685378840000,\"value\":55.6}]", + "battery_level": "[{\"ts\":1685376840000,\"value\":88.1},{\"ts\":1685377840000,\"value\":87.8},{\"ts\":1685378840000,\"value\":87.2}]" + } +} +``` + +
+ +These examples showcases using the **originator telemetry** node with dynamic configuration based on the substitution of metadata fields. + +
+
diff --git a/ui-ngx/src/assets/help/en_US/rulenode/related_device_attributes_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/related_device_attributes_node_fields_templatization.md new file mode 100644 index 0000000000..abfbd777b9 --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/rulenode/related_device_attributes_node_fields_templatization.md @@ -0,0 +1,132 @@ +#### Fields templatization + +
+
+ +{% include rulenode/common_node_fields_templatization %} + +##### Examples + +Let's assume that we have a moisture meter device(message originator) that publishes a telemetry messages that includes the following data readings: + +- `soilMoisture` +- `windSpeed` +- `windDirection` +- `temperature` +- `humidity` + +Depending on certain conditions, we might need to fetch additional server-side attributes from the related irrigation controller device. + +Specifically, if the soil moisture reading drops below a certain threshold, let's say 30%, this is considered critical as it directly impacts crop health and growth. +In this case, we need to fetch the `lastIrrigationTime` attribute. +This additional information can help us understand when the field was last watered and take necessary action, such as activating the irrigation system. +However, if the soil moisture is above this critical threshold, then we need to check another condition. +If the wind speed is above a certain level, say 8 m/s, we might need to fetch the `lastIrrigationPauseTime` attribute. +This additional information can help us understand when the last time the irrigation system was paused due to high wind conditions, +which might help to make more informed decisions about when and how to irrigate, considering both current and historical weather conditions. + +Consider that you write a script that depending on a conditions written above will add to the message metadata additional key: `keyToFetch` with one of the next values: + +- `lastIrrigationTime` +- `lastIrrigationPauseTime` + +In order to fetch value of one of the following keys for the further message processing you can define next node configuration: + +![image](${helpBaseUrl}/help/images/rulenode/examples/related-device-attributes-ft.png) + +- message definition that match first condition after processing in the script node: + +```json +{ + "msg": { + "temperature": 26.5, + "humidity": 75.2, + "soilMoisture": 28.9, + "windSpeed": 8.2, + "windDirection": "NNE" + }, + "metadata": { + "deviceType": "default", + "deviceName": "MM-001", + "ts": "1685379440000", + "keyToFetch": "lastIrrigationTime" + } +} +``` + +
+ +- message definition that match second condition after processing in the script node: + +```json +{ + "msg": { + "temperature": 26.5, + "humidity": 75.2, + "soilMoisture": 32.5, + "windSpeed": 10.4, + "windDirection": "NNE" + }, + "metadata": { + "deviceType": "default", + "deviceName": "MM-001", + "ts": "1685379440000", + "keyToFetch": "lastIrrigationPauseTime" + } +} +``` + +
+ +Rule node configuration set to fetch data to the message metadata. In the following way: + +- outgoing message for the first condition would be updated to: + +```json +{ + "msg": { + "temperature": 26.5, + "humidity": 75.2, + "soilMoisture": 28.9, + "windSpeed": 8.2, + "windDirection": "NNE" + }, + "metadata": { + "deviceType": "default", + "deviceName": "MM-001", + "ts": "1685379440000", + "keyToFetch": "lastIrrigationTime", + "ss_lastIrrigationTime": "1685369440000" + } +} +``` + +
+ +- outgoing message the second condition would be updated to: + +```json +{ + "msg": { + "temperature": 26.5, + "humidity": 75.2, + "soilMoisture": 32.5, + "windSpeed": 10.4, + "windDirection": "NNE" + }, + "metadata": { + "deviceType": "default", + "deviceName": "MM-001", + "ts": "1685379440000", + "keyToFetch": "lastIrrigationPauseTime", + "ss_lastIrrigationPauseTime": "1685359440000" + } +} +``` + +
+ +These examples showcases using the **related device attributes** node with dynamic configuration based on the substitution of metadata fields. + +
+
diff --git a/ui-ngx/src/assets/help/en_US/rulenode/related_entity_data_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/related_entity_data_node_fields_templatization.md new file mode 100644 index 0000000000..8b01a5ec2b --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/rulenode/related_entity_data_node_fields_templatization.md @@ -0,0 +1,111 @@ +#### Fields templatization + +
+
+ +{% include rulenode/common_node_fields_templatization %} + +##### Examples + +Let's consider a scenario where we possess an asset that serves as a warehouse +and is responsible for overseeing two categories of devices: + +- sensors measuring `temperature`. +- sensors measuring `humidity`. + +Additionally, let's assume that this asset has configured thresholds set as attributes for each device type: + +- *temperature_min_threshold* and *temperature_max_threshold* for temperature sensor with values set to *10* and *30* accordingly. +- *humidity_min_threshold* and *humidity_max_threshold* for humidity sensor with values set to *70* and *85* accordingly. + +Each message received from device includes `deviceType` property in the message metadata +with either `temperature` or `humidity` value according to the sensor type. + +In order to fetch the threshold value for the further message processing you can define next node configuration: + +![image](${helpBaseUrl}/help/images/rulenode/examples/related-entity-data-ft.png) +![image](${helpBaseUrl}/help/images/rulenode/examples/related-entity-data-ft-2.png) + +Imagine that you receive message defined below from the `temperature` sensor +and forwarded it to the **related entity data** node with configuration added above. + +- incoming message definition: + +```json +{ + "msg": { + "temperature": 32 + }, + "metadata": { + "deviceType": "temperature", + "deviceName": "TH-001", + "ts": "1685379440000" + } +} +``` + +
+ +The same example for the `humidity` sensor: + +- incoming message definition: + +```json +{ + "msg": { + "humidity": 77 + }, + "metadata": { + "deviceType": "humidity", + "deviceName": "HM-001", + "ts": "1685379440000" + } +} +``` + +
+ +Rule node configuration set to fetch data to the message metadata. In the following way: + +- outgoing message for the `temperature` sensor would be updated to: + +```json +{ + "msg": { + "temperature": 32 + }, + "metadata": { + "deviceType": "temperature", + "deviceName": "TH-001", + "ts": "1685379440000", + "min_threshold": "10", + "max_threshold": "30" + } +} +``` + +
+ +- outgoing message for the `humidity` sensor would be updated to: + +```json +{ + "msg": { + "humidity": 77 + }, + "metadata": { + "deviceType": "humidity", + "deviceName": "HM-001", + "ts": "1685379440000", + "min_threshold": "70", + "max_threshold": "85" + } +} +``` + +
+ +These examples showcases using the **related entity data** node with dynamic configuration based on the substitution of metadata fields. + +
+
diff --git a/ui-ngx/src/assets/help/en_US/rulenode/tenant_attributes_node_fields_templatization.md b/ui-ngx/src/assets/help/en_US/rulenode/tenant_attributes_node_fields_templatization.md new file mode 100644 index 0000000000..a478bd94f0 --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/rulenode/tenant_attributes_node_fields_templatization.md @@ -0,0 +1,107 @@ +#### Fields templatization + +
+
+ +{% include rulenode/common_node_fields_templatization %} + +##### Examples + +Let's assume that tenant manage two type of devices: `temperature` and `humidity` sensors. +Additionally, let's assume that tenant configured the thresholds settings for each device type. +Threshold settings stored as an attributes on a tenant level: + +- *temperature_min_threshold* and *temperature_max_threshold* for temperature sensor with values set to *10* and *30* accordingly. +- *humidity_min_threshold* and *humidity_max_threshold* for humidity sensor with values set to *70* and *85* accordingly. + +Each message received from device includes `deviceType` property in the message metadata +with either `temperature` or `humidity` value according to the sensor type. + +In order to fetch the threshold value for the further message processing you can define next node configuration: + +![image](${helpBaseUrl}/help/images/rulenode/examples/tenant-attributes-ft.png) + +Imagine that you receive message defined below from the `temperature` sensor +and forwarded it to the **tenant attributes** node with configuration added above. + +- incoming message definition: + +```json +{ + "msg": { + "temperature": 32 + }, + "metadata": { + "deviceType": "temperature", + "deviceName": "TH-001", + "ts": "1685379440000" + } +} +``` + +
+ +The same example for the `humidity` sensor: + +- incoming message definition: + +```json +{ + "msg": { + "humidity": 77 + }, + "metadata": { + "deviceType": "humidity", + "deviceName": "HM-001", + "ts": "1685379440000" + } +} +``` + +
+ +Rule node configuration set to fetch data to the message metadata. In the following way: + +- outgoing message for the `temperature` sensor would be updated to: + +```json +{ + "msg": { + "temperature": 32 + }, + "metadata": { + "deviceType": "temperature", + "deviceName": "TH-001", + "ts": "1685379440000", + "min_threshold": "10", + "max_threshold": "30" + } +} +``` + +
+ +- outgoing message for the `humidity` sensor would be updated to: + +```json +{ + "msg": { + "humidity": 77 + }, + "metadata": { + "deviceType": "humidity", + "deviceName": "HM-001", + "ts": "1685379440000", + "min_threshold": "70", + "max_threshold": "85" + } +} +``` + +
+ +These examples showcases using the **tenant attributes** node with dynamic configuration based on the substitution of metadata fields. + +
+
+ diff --git a/ui-ngx/src/assets/help/images/rulenode/examples/originator-attributes-ft.png b/ui-ngx/src/assets/help/images/rulenode/examples/originator-attributes-ft.png new file mode 100644 index 0000000000000000000000000000000000000000..071948aaad4dfcb246df46ef4fd972d50ab29680 GIT binary patch literal 73529 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 Iw0iRY0D0GU4*&oF literal 0 HcmV?d00001 diff --git a/ui-ngx/src/assets/help/images/rulenode/examples/originator-fields-ft.png b/ui-ngx/src/assets/help/images/rulenode/examples/originator-fields-ft.png new file mode 100644 index 0000000000000000000000000000000000000000..c32cca8eae0835ef46e837343ef715bd579f9a78 GIT binary patch literal 70946 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 literal 0 HcmV?d00001 diff --git a/ui-ngx/src/assets/help/images/rulenode/examples/originator-telemetry-ft-3.png b/ui-ngx/src/assets/help/images/rulenode/examples/originator-telemetry-ft-3.png new file mode 100644 index 0000000000000000000000000000000000000000..b0dc22cf8a7c5a9c81363550f96f5aac7cec6812 GIT binary patch literal 78213 zcmbrlbySpX*ET+kBMc=&gXGYif=DwUsdP%0Aks+J(A^>-AQFN!DBT?rf+9!`4Be$P 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 UBDcdQalpTa_Z6iJBn|!lFOh^s`2YX_ literal 0 HcmV?d00001 diff --git a/ui-ngx/src/assets/help/images/rulenode/examples/originator-telemetry-ft.png b/ui-ngx/src/assets/help/images/rulenode/examples/originator-telemetry-ft.png new file mode 100644 index 0000000000000000000000000000000000000000..688654f4ee12208b5861b3c392ee8c96358c9141 GIT binary patch literal 69883 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 R)(!zb20F%n6yflp{{@=rF=zk) literal 0 HcmV?d00001 diff --git a/ui-ngx/src/assets/help/images/rulenode/examples/related-device-attributes-ft.png b/ui-ngx/src/assets/help/images/rulenode/examples/related-device-attributes-ft.png new file mode 100644 index 0000000000000000000000000000000000000000..2dc89a27baba86bf12032f0f5711baac89808da4 GIT binary patch literal 60303 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 MSn_H16HWL32FVo>_W%F@ literal 0 HcmV?d00001 diff --git a/ui-ngx/src/assets/help/images/rulenode/examples/related-entity-data-ft-2.png b/ui-ngx/src/assets/help/images/rulenode/examples/related-entity-data-ft-2.png new file mode 100644 index 0000000000000000000000000000000000000000..36c526928d66b75fb8e3407da6aeb572a183497a GIT binary patch literal 76684 zcmdSBby$>N+civyfC57!ARW>o0!j_iozf*B(jp)Y14x5NcS?76cM3>%2}t))0|W2H z&-=O6`}^+qkMED~I3A7xIhWP5$%Bh**C{T(%8!b@dx4D4k*bu~&a;HBYqDQJuUz#|i91vfWilpC~?X_So zOh(^3^gB20=!$p8u!ZvwYKBK!0P(l#>=>GvaKbe4xw%Rz{Cjdg=dSk0dpe5u&NO=| zF1i*FLrnB;5nR*t@#c%)w^s@3S(`LFpLA0ngz3piI=!IsRMy~P74h4LR9xn2!d(afcd zcXW<$0I5d~boYPq?a#CsrRa&~WN*BgY!Mh;%+__~CKq(ue5##Ab7XyfFqr~z)jN;% zDqC;OqI~%gmVnaav~KR|#E%|^@W;!u4aHD2lpz;7LeWx}G%K@Izt9eb%*DPB(e_x#G#_F4 zkB=##G&7}A`^17@%X`Q{=YIa|IauYHf0|ETDe`+@cY}O`>!r57SQY>o&~_@)U%WSB zt#Ftjh!3Yf#TbnED|%iilrSaBdoAndN2@&rA&qA~w>}{}n1vW};eUP(0X^>3@<4gt z;|DjM2KGPwLlsLmgx=!YTAQo+*9t!gx2c~Dg zll;eMR#3EJqzK!`D5NheQXo5r!-r%q6ayjJZK2p36mDjgR;D4pJ9^jY z)(=P&>mh`~YpXxB)aSj!__;lw|akoFA=A~2B{ z9x_hDn>H!PZqGw+qlz3uiZF}*V+x4nmn$LyMJ(5<&Mpc(EYg=8XxQlyRB9GD z|6e0PNQdi-u~#;XUtP5K`l#eJG2bn*i|dUMLB*#R;5@b+{{ zAGpc{3K%PMlcy1E8unMr9x@<|gc>qmvywVXgpgzz!jvjQ8nrCJVl6B1SKfaQ?**d8 zh&7LQXw~LayW8_4u=^Eq2eas39|}(t8gG4~{MD3=QRQjk+P5g_2-<)Q{_&avaLlSn zNq=?|!&*sl&-%m;PdI7RgCc7+mRA9Bke#O#T$N~wIUNOUSCsjq{_1Hv zy<)YZ!`6IdP^L43QrvyLdWgE;Hx1UrvlLq8$0!N-Aq-w#UQ~MDv$A$Nw+Kh9ch-9j z-UZx1thOajM-TeEC5AH%3)v^kU@Zs%#h52Zyw82ZrS;F&u z!L|i@QV1lHq-$*lb^UFhAN<*e?Nq;J6hceN8ka}ue9d2f!pb~t&bF4n)~9YVVa#On-4jebxd^G&}&Vt?La_kERc(!qmt za3S}X{i8hm;Y7`4gS-hyRM!5WMKox>V-71RrXz=qw7)ZjLw(=gbt7>hG#h#O-rZWF z{DfnAW#fF=D4z!^s&`vW`5adv@9hX5gvTXW(r;WU%i;t( zv!_?g_I70K=}zPmh~?I;obILZcB<{o_T#Y~tdSCQh}^C}E_{;Isp!_KaOUdQ|J^*wMS=T(kI`TLhGCyaewzvXM^{AKnEJpj*nzme^WliK12_T8ljv?I z_d*j*(^(;V2A%W!igKGHz>vR*z4PfHK@+a+2fF!i>`1m&Uoma!W8}&me!et7o5Qvk z#qN=`uXrJH7Cga3^B~8*b=>+Vp6Qska3*iq=*K<6Y?KDe-)>)fmx~ETrK0e~shgB9AwYz<?CdQg9dx?HaxYd36J}$pxI*8one&j+{(Bh^c93I)PkD zmuGoMh!4VLKAg0QA9o(DZx6aYGnrtEZ+YjKJJyCYU}~!Vc~fcq$7w^k;mND`CR>SI z(r#6V6mEC)Bt>-evwIcH2M2=

G$y7(KHYp?5ysZE3=5(w>N5qO%=1)U;T456LpF7ligpdy#Dsct4oh@BL)&DpD!H zGLp(D_l!W|La+LH1nn!GI>?5XUmVzw z*s#gL(FBQD`A4cHhOZVl;4T^#rnZ35>SG=&qI97iXo7l~hX$TrIzgFO-xJUcUNW(`>;byWCb+!4S*;T5KPG-os*r~-gm1D(@MT=j!tv|{yO+Hs6zH5IF8aIcm}{~|99QW! zyO>|`yOxXE&{@qVLlHX^IHd<>U1so& zP$J{5LQ|!>$E8$B%j(Yz{PidLqbs;)gKn%zRKwcqIHij}GfoiKJM4JPLk>0M){5sF z89cu1=gv+$w%ck#rvxX4@TKs2Q#1H-Jwy&gF8G*==XbD175$spoKhH7CjhCdHZ+=A2elzvSp&rD-)TF!PqPsf`%xn{H2SG_^H$pR z(|3U#i1~pxeAp?yMDE#ns`s3d7;e7nI2U85G|~>b$|-FaQ5F+V=oMuOSsDl*Zf@D- zsT~VcwSVdpzm;M(ZkrX@c2d6#Ihc4&nINxMOQq{S7%RiGFTLW(*?-7JQ4o^S)Wa5S zd|SNu#u@9S)5dk3igWd20*et3=r`4>bT87|?#GSH)I!Fh(jcCg<#)Hv{S^7uf;VXa z$Ipx&PP_+87sb55h0jW3(S!C-hr%~rvC~QT;eTo|qDDB|M2;#I)`yV>%aFf?Kn>~ER=WZjcNiR$QpQ#) zruw1A9@^hLG)q3?o`c>=?wCDhOUERWgNl?|B~QYO5cFy_(H)93*cpIbfVqY&;=n_f zEIm&=;6~MmmudJ#Cri6jrE=4_t2BzCzQ`6KGV7wF_GH3l>eYt)rSUA&K#%@7E1eZd zjJg2&8fN2OWRDm00VrVUQ;URZE{mh5p}0f=E5Q| zkN9EK{tl0h=nokONfRokcDI4duU|w}aMv@zaA1C}DDY3J{Dqm6uOGN?f1_FLZ~Edw zIuTktZDU4x^5&m{)JqYiS{5$3MRb{vdxedXE2XwqwZTXDB;Wedz zM|->H*-V95|G8pZ_k@4$0laLX_W}D$ZvQmO8%V0Eo|`&%x_L^AbAcnXLb<(-I+TXq zb>U*DpOzmQTFA}T6ZlAXc~8_Ut?8=uMi4^|I(%uAqjmW`i2kt18p%hVN@X;~XhYSl z#y(G#JN5XCraVVu>_(clp&fg`P9t07r7bK-!@5i^+JPi?d#ZNOixu9HfRloOgZ#SZKkc?FDbXClt_(97uzI zuzCv!mSmsFq#&Kbm3K1aR!wfXEU0F0 z*=*){U4e^+BQZ45a@MYWMe)PB-qh#XxzOTS8)LE)jbC%{9i>|SO5R=FUlru;`NZcV zBi_JnYV*ezQbHF@%^Pl68a;;@@(`I5&+o=l+sAnE!z7) zz;0DiOAYJzVZvHmc66NFd8GT}Txq>s`kS9B2&~t%hZfsyuK_Saeg=<3U*NO{kvYT4 zki4SN@OLMKOmT&~OQ}eB3d!%nLp@*E!4QqIqCwC?MwY(qBG$rO*u)4cI?%Mlm!L=W zDQePyiZy8Rm9_DTQv2k{qC4J<$_x`ww0N%^ke4($n>|?0KHOB0$KFHrLThJMCtqPIW!d07%-G^X5j7&G zPfGoeBbnU!`r>LCK0%g|&}j5RMN=v%1Kp04%^vYdd%R}VAB!$YZC?b6zcelvLyh3l zzL^_D6AQ=ChW6RHbp5#uZ=C_s^OUezSctCoJZ|AD%^1;evi+`|?LewK}#&vm%M+NF=p`>b6`%&%v zyz`TZ*@x-|Agv_c_LodmBc9_u|skN zxdJ%R+SpZ@36;%9AbORS6Jmmh6%24DrkJi`VMUec>G&9-s}U8;2sUuid=7Du3^6}d zc~NENNz^PA^B4j8CUj=_H3I*D^k*^s$Eel z)Ne5@*hyF?laA|pJoyy5Rja!*UBgoUP)+Uh%TJ6=oNC>948IoMTuC~~bL}RTj@oYb zty*h{Sw5_zg%xpLw9ehmHP_S)bZCbyV%J?FzM1nH8+B;iRm?7o-Km0p2Au}`SF3VN zp&h;Ya+EXdooN>GgK6Vsko{T8zc_$A%oeo!v-WF+{lQr5)RtdsX<($U*;p39CD}ig z!+r17EsSMJvNW~i(>YgUsh%aTZ&^>}eyY4E%`E3I-{-w_A0$V2Ia0RD-@6pUytJBN zi!NDGvJrza$b%$|4+05j5~PO%F_W-U`SC1Cx~p34m&a9)=kk-cZHtdPMDOE~?+$JX zybIjc4iMO7H&trLoON!oztuL--Gb{VSAW1deeY>xQo?JguaQncjkyeH9z5>!ef+Fk7albfh13@*0|kvcoSF|I=oHl~ zQ&?>1O_Y9iQH(L^c>!i?FH>3#1;;B5!TjWW>=@>wpJt8fX&>7xM_a6Pxuhl{nr*y= zqiKQ>Y#Pu7xcc&Y#K0nNiGbey5cIgSY;E;RD$MOQK~`F+PcQPDClAPk2-7FwCVeX^ zu@fdMePh-Q;Y1EkU&88i1qK>W3rhk+I#^v4l)j38F@#mIaO5`wa*gLL(&8C1L@P(u zw^me*a>pOvkkbFLlfOuck` zPXmJA$cdC^c#01YF#o_Zm)TaMUkDvwyuM1xKbo)e>hKPN%qqB7+fANhg>Jpro$X>47 z;W~?aT|VrV!PNcSS|*r5j$-k{W6k7<2nHDvIyLsCT4qTp42OWk3bx{7k(d zSQfvS4K0kSk@PhqH6{~L#CRWG-(Ul_aa+AW1eK~X*O}${gJr9MC3ii!@+?=0Cib*T zY!w#kMEfiX4n1v;*YeMD;0Ga%PGtn`(a-=$r4%->2Ee<#<{302p#-#r_ymKIQYiu+ zU)vkPQdF6VjXV?%is|1~n@M+&%>62<3LNHLK*w)?2?b)U;gR=KU*f^>h^%5bPHtod z_E|F}w@0d+Rkt|Izm8QVfo{O=DhjCbS1P^%iMshF?s;qmSK@lta)A&h*yAo}!_F2@ zgH5FZ674b{%3(XVY&0_QJVw0Cb_CFi)rONUXWF>P2~QS1`Pw_GA(3 zRrC2YxM0tBlivvcpXQbW5V+6Po+PO3-5&_&$ig7-qq!aO?qPyHD!YSHcIR=BZ=!8j;e=q&KPQiR%>0yM-68qW~TtYZ_^67pN;V~RU^$Ry{`?pJhy zpWf&ifTr?L&>#rnbnO8?)Q7lv?}*v`#ZwC*q2ic^vDahlj5J=EpS&0HJig(>hijoy z1VOxAyx#o^;lF;iiXwsFT0hAFI?SNMFK<^sOEUBfuRS$=sWauP*}t!Q_si1&&#KLu z(=+B0fSlcHN(xS2O4Cbw^!I1NJ&QK6>8=@Ja+wNae|2ja5lLR`_WM^6R_nDY%%iV4 zOUM8b^0)kzi1K{IdT(Wl`zW8-BM8ESe)93J<`18Fm5R0mZRKp9+hQLb|J^=4qHenW zz@pLPMQ?ui33l_xlVkqmzbJIcR?9nqx05ID_p@IU9QzV4=}}3S*RrIVgop({Uu8gOCbPw8xCYLJOvU2p=t1}{<~{BNcixd$65A&2bmW! z2vXvR$oz-E2z31??gu8A>-qlU&rFy(1|R>&3qa|&0niHH{=2?wYrETe+LrxX>6+k82;9ghP^nS9s%f^147Xq z`}^;g=M2inU?#GwvhHs9n$O-|xxX z*gQeG9m$Yb@4yB}(Mm-~&Q_Yq626vD z+{nbTNhR~z)4q72vA@{F%;&HRa_ZEsGN)ry&iv4p(A(sC{+6%@2mx1z2|aabr#Z2a0}Nwwncou)Lsx|En9zaXJl2a*L&<#F zLoP=@d_R+LNq03mZhn7Ngs{oFLeTSNmy{Leaj|lrQ7PT$b)K@Ab>z6siWQMqi%gvJ z)884gNiQ@~LK;0y0DtkA3LFP=JDpIEU{s+u#)%HVb*J`)oF53m3zNEQNSP;gpXdKYkGUUJ`nv~A(kz9ma@_L*q@z>aLF~OBr1EglC6u;8z7wqJs%stg%VYjDui2 zKENRhOsORfbT}1EG>*LJA*=OQ=X4l=4GM`9fd1)~;vppcKMK@KPz-qPW05K9*Os8 zBYvmf0x2q_vA}GszCa%?FCp^D=XW|3N)d3)-rhBrN)>Ec$CpT_pyCAITo?r$rp#2B zFk6G^5z%D4h{faNR@!}&gCGJM+c@yeiv5KK=3$pS%d%SXonPMo6QJDEN%E^!HBX$&MrRDORJ*FmE#y zNFvuN^Y1>n*b&2~fhLttK-c6?-}Z(nrc)T=B9%&nlIs;URs@S20wdAw$}keiZLp5E zr-cEIG>&hg?p9F*scSKVjP68&0Fz$lo{}$7n|CN(IB&2t|6u=XCgH-DV2q z1@}ohass!NdEa)%xsL1JD?PYQovm;0SV13b=bFr>g#$@^=Q~Wx5RxF`Cr$ zo)@ItQ|Z$dM5yj95cq4!aQobmcHam0NW&AKo3$U3)1We1{X3EuWL`jk(9amnrL-HB z+R#{G;mXhC5}vE1v59leDKlR<8EuI={ zaXK=L#*vc2+YTZ1pZWteHKC;4`$`qw^j(`yI2eNVdMD1!kxF}G(tnDK8BLN4{V4va zK|APY*=J-Mm;L#dbj?(qRJJ%bqiL^@2g)Qh>)tQ$8b5gCpa@N|m?NK-pnv?0ma4UC zCeuCz!oqCk3{xs84a$hMGblkCg%}WbpAEsUM$^R)IE1fA0Ak1>K$Yx+p*UR~G$tq;;MD zv{ngq(k)x*N-KDDKGwE;^t-t*&rkqm@RZRsVor5tk39eL9SWSoYPPJLrBKud1=7C{ zN8067;5u@V6*LJ5xWd*|oI=*dT{C4)?*XXR`9TjZ|O-Z5jsl`G@`lDZ)rN zu|n0*zV(Km(OajXwYuM8{?WF5Xc4SE3N^}Pk6oJwkJ~{|vL;z_ zLFe~|4@?tKu49F+UvOl3Bx(U%1=Fn+iiP|?vkuxqqwEIDC%y1{;KBJZk2x6##)Hb| zZ5}_5S+|}#A>M0wuQcO$zQt&}xkyM|D>Yl3|H=xL;qC30-*1 zcwmXR$nNqae9=GwZF7D#Sq+$YQtkH-_@!*e6UtSXueHIn$hk}ZppmhXNMfG7ZIrGK z$yO}H_xtOmzlw%K2_*6N`+#T928H+@(W1N4<*;5IYwBsdv0;c=0tz*o7h@CHI8LE+ zPp|s(UE9j3th`N}vL2^>GkHGt>mn#Rl_x75{>RYE2YDk9 z7X8Nc@RU_CYHGyBR*SBHNjE!d(OsSDz<+xF!t3H_wE_N9kLF_@UtF>ajHY4J-=8Ao zri$-2{3cSpt|MWCM0D9-jVlXq_>AVxIrYT|`hMP=lzdk_%_d?}%(02_+=$RCCDns6 zI_T%q0scLgfYv+c2NZPC>0-gsF)W(=A651IP_F%3z3*ec1&~O@OS^ZBifKY|1WT1> zk$3PDz=tR)usAGw+`8W)f)Fh*6aevaA3q4Z+RW8Fgp_|R=N|D=s{P7{;~@71?wlQFX%w=B5pt$Qn{Y(h6A8ZdVjtyxqK8$ z2-gePQKbPBE1hor$NJ$4f$#A^eX-vg&8$vqzdarSlpRk?Rxtt92i}eu$PnTA00ls% z>;S@gXphR@zTO{=7jSt8K8tngfW38jyTG3W=ZBFGo4r4_09<~PLoSD}V`r}}*snVL zb6#Zs&Xjd#|5V4?5WI&lgOtHOTHSh4vWxwGK?~;oxDXTmAfr8RNX&`)d;j_uhC_wt zu~BSctn=x&tJp!(HG~wB{}S8xd7=oDa09+=@pUl6xD3Jt-CYLzlAft%q5$f059iNTFJ#-BYv<_a2q|X(T6qvbe|^+LL8yn0OB+VQWscT~ zs)h;Fiv`@V2I~mqVo|F-p%3_vUcGu{ZcpiPb8Rj)oAP+D^k>}^WH^R3vHm7YCUy-V zrB*WWi01wl}5AWm;t05 z>A2`D0aTm}ARQn-mHgTCn{@zEgcd+Lsvag(h&1S?=@hG#Km|u7Yb5(4rK3qPT@>Bl zh;(&S4QkX#!SAHFfD9n~*Q*o;!e|F|4toi^b2SPf7V}pcVjsArc*+OEX9$xpG`ehZ zh`-7#)Cu0DF%=tjmRkYNd?)FbaKDQy-t`BP@FAnO^XGEwM-`NLV@K-7dBWjIqZ>Qe z6CI^XodmY$ZAO>bHe!8|bX7sa`W5h8H|0Hdy6V(>O;N}UZ2dm>5;HZ6aKDOz1@)m* zdcem*-lTK5ooQ*-uXu`#EIG7VnjINP<>_*#vS_yGL-Z@O+4NeN0e=JyN4i9$@6MTI zIDb4XU;!De+@K94;H>`)cu(&9d}>yFEPEuXuRRLJ%}eu1g9VYMzcoPIT;1^?)c!maKS=a1KvN)GQ0oPY*=S}2g95o!3`;zVcC{?JdFR+2h7Vk1QqAuL%A>WC zmK$YZL_=ge^y{K`g9*|vH0HcaCoz&pd%iqYnfg=!#6|n1!*FA~LrCi&DZjIg5`iyFYabyB6 zuO}W+V?-kQaD8RH_ki%BD%eL)7@9$=kfKvXG$kgGuU^6il-SWg+U55Nbp?GRA!vKg zkZSs+Du?2{SZ(=K!U5l6OZ4&iJ^In_RJAo21WdFK2w4;jDbDfs z>0~pRRr53V5eZMwm+RK#zivAEr$pL?c*=}W++YO(=Gj8hB~7-4+8pkM_6jVVr62x` z{U@P6SQ>LwBKxJG=Oj&{YLcx`icsgIIQnr|Y(kbxb@>L7+>%XOf!Q%&|p+*Mxneh+DGxoJ> z-m8+5fnl38>s>wOp9mp7@cSTm!hQTbFSOY*BmaaCo~u9sIw6fnPr*X_<~gDS2Yh<@ z%LK2*2*u=dcT;vCL{%pV@b9w8F*o}Uu1vX0Y@EJ2oaW*QGN zMMkWXn@p}gliOb17@3XQMaZPz0`BTe!14uHH-a80ID*xN#{?o+r?0z5{U zE9dJ1HMt3(CLIQ-J32lLdV&W;Y_B8nbtv?d{mw*FHiC1s^LZL`oQ{4Ne6gAz1GuK9 z;An6m!W*t3ZdYvj9~$UBDhPPmvZx;vY{9{oO~Z#Nl3_Wiq|O~4G;-SuIv77;)_p1! zJ|BoJ=eruPL3Xz=xl&`AgS0OcQeEeEn%u|cz>P@h`X^9^03w+p^477XcdaZ{*2~L% zGNX-C_+GKj=Sg}@*#JoLQw{2MOjQL6_ag1Do={kM_Uw3r<=C96@8$^7M7NR8b*6NT z;u$#~`^#t9QN^tJ(m$W~WlHaSwLRI-I1~wbYhp`N;y%)1HOEZ=@dgn&?eJJmr!8V5 zjfAE$s}+_y!EmrD>^9^HdV<$I@O^%?j^#87kWsM)ocl|5OC$1c#7Sz*l|6PjT1Q?y1#;xz*>ke zw5u_tZ~_Hxry;|3Ks#zXRbl{QT<-t*ej>o@&}4%P%R*cSC&x+_{DB*d3iqjk3HI;H zeki+L2gpG4VTATMjc;_VA&uceP)=i$i}&fz4`?HdX=WMO0UJ2I)@M`d=HUxtrWnXk zX>|mfv0;3TdF*HXTB%ux&Z}*8mfUvJ(iI{`ew@WsS*QgE{3T~r1k%gVzTTHRuLFka z(U+t@)t24)O(Ou$qVsK&tnFpD03GZf?`cg*&h`tVONSYoi_a|NvudE2%8wloRTHu? zX3DD(vJWr>&9CD5?jwJ8z8T<~l<hZKo-*Dx5fmc8rBK-9vlTeuSnZwD6r= zT@~}# zpNi|f#yocf_{i~0@E}PxLOhDs;1{KB@9Q+|0=ml2T6A35xOW?e~6$tadXEH zSj-Ef&usVgpV{}R1>>+LV)Gvjy2!;abuC2~4;Dzjd4qphJLeRL$65bydt6AFR*tf% zhb5f<_T7OEJuH0TehG=lzXm*GfLp0R67*zeELorfUQG>_h8!l9EX|=?|uO2`tfO1Y}5T}9C>dO zdQrZ{n>Yl((uFgcY4xO=7WvfQ5$}csLgQ$cMikB}1q;ueEXNm|Fab;kPP8Y^SAjRHC+RJg9ZYRD z&vIfiZ<|9YUudii?(i^GbQVf3Z%HtiC9V$rs!$1(dY;dTA!Xynjb5qrMZsD$98}oF zSHmL^P{8fshw0BcPa1ZjgQGw*roe3*iYQ@O53hpfSq0f)V_7mpEF+OJUldNH`{UYh zABll^ADKZxG<*(igz+_gW+V%bFZjW>IHnqPX_dwLOtxGJMZY-wLsz8f;kV7&V2yrwqkUsU2Io#&y@TS`vqLWzd#k^0xx+LfzG@7J<6u>)V@-T2Gv zhNoo2DqS@2{%~^3q(W$0YLR0Fz@=)Y87Jv4ifZ{5oHb%RAf&v;n(LL#h9$vXAlzsX|JWZl3&q&BaXaugIP}et~;{i!B z-_EY&K5uyJAs^Cw<&L9nH^wjWCLlK!L{eooMXp$3pI0IO)+v-zSYFV7io)8H-{vNP zMWaUlX5Jx+{m?d&QQ;hna zI=)4II9mJ^%dX#FvGJ<>s@HkO8Ja{UXs=ql0HF*`MYW-RV+bCrG(i_y?g@D;qD&jY zt~o{@3#?$tz{dECY~5i8KF$fDOU@8=sE(rJH0<2YOO75ED&tRV?@Ei*DH)=h^ z|E;M3yvYY&K;2`m)Zw3;`=DFMhW)4Z9gy~m(+f>Q4j!cbx9)?8d-xb>kr2Mn;Hdsp z7R|a{0pE%O8G`*GDu;q&x1u@qCm-$Jc<0;)cM>e-KW|H2=0IAU%#s&?b6KoC6m+5$ z8lCXaf5vcUIKhXLlhQPT{^TH2@eZ9wQrUFt-vq|%*ghX(W;8;T0qzh3SQDT0rC|y3 zf)jES&&&QIECv4|EZ-mfm%sYI5SIT7xmR}V7_nf& zK0vu#yVE>kE!qeEc%RuM0Jl)JpVN0iE)A{rz{<8U}?F zjkrzTwxL&v+*T2Q<|4J!>^{-o2i)FEC-H@Bg{$Y}x2)Lu6iIx0^ze01x;_J!(?p4G z1O3KuYOI3br6|C{2^`d575t5n8+UiInz913OJV-HA>TXt$<4Uc&DT#pSN`qP&nCb zesn7Bd0ljOf*KXsWwAz5N(GUTE$D$%hy--Ffp|_6TGjm5qb(jD#uUbYFJOBbU^)w6 zX;{k-vF^CZo=^%I;8_isue?!}TOjVq0^d6R2qpiWf2B11p~OVJoy0#IPVGegTjk$Wj2Fi|4~b zk9(&8+wYC%MdCBPmV{ic6Vav3Rar3XOqHmAWe4h;N@f^`lIe8m*WLL#l|VOHwmU-9 zVyam6G@jqNoZsz2Q4URU3X|LkZPR!lrVp5@yN&r0H1)(q^fr#eh!!A3x1F@TEPxx$ z(jCTgm7cl7KE{gPIk8mZ6oAz^!BzUq=Jv*&4oVepWq@_PJ`BEnO@0P2DNIVCOB^dgP7&4qh}0C!WZ>&Vk=zeiK#vOu5G#8eZaOM2pBCzujXfT>jpqNpt(4oCHnx}q(= z^p6Dt{Lg5

ujTW!!{2H?DpM%guMZT1DM7rA4UHylT=SZ;ufroH3;qTAJ`Qw3br z0zceM2*4-hssJi?LMwECLE9IvZO57!hNBE!ZbM$bY_VMr%9Kx@?HmCB#lPJ~X{nw{ z^{;OUM98HSTJUT^5umukDD7VqMk&zO$;AVJ_{mkIW=+l^9J6L`yq^MbI!ffSAj}s# zY^Qn1ApV)yyaln{2y|tW0D;fl6*#0eGTQJ&ME>@3HO8H0*|39Y79FuTa1Ee3 z^5oKix?RcU;_z)OtF{_IKNWv@_2fZuh=!w2`Wscs!b9@TVr)|GZ@6QjgC!brLL@TR zkAILvVs)0#R6kCqaQBp}nXV1~KqiX?xjvG3#P3vk{DED!{x!OLCZ?}H8L1v17E=SO zHTG<8j#BH4 z1Md4YnP@h*lddfDB+vQdew@Z!OHUwB)-1g%ZZxKi$x;a3U_MWwCIZVUKUj9RRe^Jsbg?`AU0YO?0lSwyJ7l(p0Qf2 zB!}XZ<#g#QmuhD>-5zIi>v*;exQTT;RYF9PlCdBPsq7T3@1K(!HtP z^pB+gN_XXZ)?hthzjKPeOc8*;g{RE%e<3RQZ;J5$KSMFC#ikI90#5zjfmn9B7cZte z6UP1!)GrvkJUtNt0qwXm5KrPqPv}8v$kVTr;ycRf1(FIaScWBfO%Zo%5|Ipe_DCQO zjo%xgihnySfL{Q)w#O9Mjrbwg8ZV_I>15~usyGB12Z-@xNaAfx4tpdf1@vclzx8!d zStP9}QQ%;sd55fP8m&}6?knT>0zje+Yfm-w8=a_thwosr8>Re#&%c5X#YI-l=3>W~scC_WLS0UfC_CJGMV9DPb zoQ~2n_p zfMGq(6o2@X#xibJlH`w)gn~gxVEul2i{rr}6BQgdh9^F>;{vCt_4qI%GU^2s#A)dH z$e<&Ks?7HHzWnAH;x^+!@C^WP3O<}ZQA*cnpF~DRRvlhFK>TGt9x z$^65%cxZz(u7VHG#!{j|jlNH|(Qml~MUm?ixVv0Dr#lTzvGO`&xgc)Wr)R9zhTl z|6Cm8Z)l|1+!5XX9*bma54xg)5;T!lG=%t#`1I4N@aMk-|9_4-LHS=pr856tIaC*t z%b#+kjc%7(dQHwWz{AB{ml5?gBO=@WRuJ)Ys`<;Kix>c|4`*6R!D!i zV_Y&y{Y%3GQeO-3t|%jmprE?X|4i=qx#Zd9!F?ywXsm#w;Hd!yjScp!unXsohM#~q zgCmEEx8>bfJv|mrJZ8oqCJC~lZkq5upi&1eN}1Dv z@V{a)UrR2P?7oep^#coe=bz6F_RZNy4`~d+2u?B3UnxB_z>ofBYjl3@1t5nv0e?2X zty*sWPim$hb6$n=U<*=|UTq8rmfQViUNUG<{l;Z9s648m*2JpVl z&!?4S+rQhx5=E&roZFMDI#sdA?|AwlhUS4Hd}Aoj=MCxWsaz(~eQZn{5Yga)hm@fo zxHvU-<_4p;B$Ak3;vMzKXO4qZZledaLCCsd(?(@H3n=N;^R7XrSF77))7|3iTHW7l z2dqx|Q`NYT(1T|`AKT*gDc%6i& z`}_&+HbbjNHb_p`LY6we--WUS50PvO7oBp5B(nlsue4Yl9R{xXf-}hg+gU( z)NZ9U>`1G`(DO$!0=&oajL#1b7p?+RPp6H0QnyWN-OelSDW%EvCUNqDnl;f##JTtP zcZXcfWsOl!ewh{+Ifr(_@it1!F@{p4RJ&N)0RJ}EeRS5*=zr4v272`#3y(~3s$%t? zOl#<;$5G!mAYMBuv{D{VqzVkxj@ugRy{(Vd)WA<(?|Cnnf168Nk;k;=Bh}a!3>|2(cCk^lu6l-89s#_qF2YTRYYy1rBo&DI zvIa6AG6T|15~U39J%_3nTDi|PJ&E^z*FFW5TT~ z>uqZlG({u^oaXCTK=q%L_T9cnC-UP*MuQsjChg)gFJWTNC?C^LxdZQHA}M)41y#J0 zmSaSp9Mdl+C=p$Mhfw&b-EinZ-1h8DFDKD~)2{GzwRc&67OGym#83^*IHVDAdIu;3 zoC7ClXlyX#`tZVX?3ml}mQGPZcNfQx*T>t|=ZAS(<Tf{!S< z?$b=5@+9_kigYMdB|fXBasd{=drDr@ZV)oL9ky92t#WT3k#y!R#X@vBeh|SH08=g3 zr2a(tiEM#JhM4>v=wYE@xerZ6rCcOA?1%Zad_!Pv*7Y0bshXh_T8GLdcF8*hir*47{L$S7#2|e+- zk2;jMra}_G59K`mf`@~JiX`vLqt{h9T6quFTE_zS&{y606@R9eBZpP;R3 zvi~Ver5aWjUXzIvj>iicHY9vU=gW>i9Ps%lWBkCI8;V7OB#9vTPVxn$sG3WcjSc4s zICM+yEBh8&HHw-lszt0ji@Ptq#egQCch`p7@V;_QXQkcKJlXKK%DHWvIK1M|to69e zJ~v%{(JA}XuyVBiGrr;cNCg}Z$X94Lx--Zg$dxTef1zSO6uQ*sl*#CLB7Y#SJmIW@pC} zn)WZRSv)gY*wjdpsFeuVf8r~`Zznxf;rnf8rrhLrz=%3t*e(>stygCHo_KpSaef{7 zSy!FpTkKI^0(U+uKFR%*=PZE4f|hl#Vnk4TvF-fmSiePlih*epwCQIEx2%XB85_5@XfZ}9*G%vKnW{-IlFz+q3meFb4S zMke;p^y(*^Z-2G=FATPPUwGdYh||^mi%vYj@}o)k+umEjqR1Qtq9Xs3GSBUm$suO@ zr5KVnxi@4=yTse~14N1Epp`d?UJ-xMJr2=q<9HX$kJTS=+3?xj*DYO?8xa<=W0V$4?MkEN6QyQP`{t@>jLW&+D&aiaU({51uGSNm zH}`s7^v&jk928V3i;+8KDX*h|Z9^O+*XDz9l zc*0{^cmL*{pki8rUvem*BN;`8^}Jq-XmQ6a^8NbeaAQc;7qOEXFr8OqSVAlHqQH&M zoS83^Y0@_IaDP!2T@LsjK zUW1Da2?zH>WX}$54LulM?`lfoyAygk2}}mK`ctITdi9EPLz{Ku?x}rQ3N9g#gRtJ{ znOEWwDV_i7!@c;k+50pzFGCc^pMjK3=`LtY#6A3GQ#fzg9{nj4mjLfMI zD)%>ZN_5qn=4+Xoe`e&IV3_yNWd^j@TlzBaAMXDe$dEMZSYP)$H5q%VKTO;=66jAad89@-r#CMnA_Wh5# zf?uboX#$w=U&uo$SjoBcpM2Ix=YXyKVqWFceg_D7z1d*|E6cGoh5HOX5KDOI*pDOY zgC+Ull4);JW*gO1(V!2%tF;TBFnMY$^^pzS5aqmq5_r(8Fjv9%SEb zqKqdBt!IoCslc!ZyOs%6#a}R~2b6Uo=Yv%9ylWPG;#H`Ura`8hwT8BjfBtsRI>7t@od)c_cRxM1 zbQ}T1Fk0-sWF8&P*9XgNPlzx=F@jDyC@TV{hDjDBYk=@bk^@>|lEXSDdUXcr%2gOJ z-Fo=i_O|X_faKfPvfZM?d=KizfB!_vOAlzr{*N827@z7Gp78eq_?p~}nuWme1GtZKx9b{fQ64pS|)Fv{{L&Qc!GjLLP0`Vz;K zc$)FzF~3V#{c$-QJ~F~ESKfy1h^jJ@Wb&H$^e|llA@XL${wd3lGp2eP;GMXHNc&_$ z{C?7~_!ymLv5OOBBo=SR^@TE|J-mHIa#?~)Pu8X>Zv4K2y zBY%S!Ho52v&#mi8PzqgQ&)p~I`G-8~C#oKs&KC4q#-xCc6>Cv~AgZ^MAMi z4;+|En(Q4%zrFOjV)^>)+--BdEEay*R6SZ?5O1v5!h*RMv?=^2{~R)*!H9YSD&&aGEvp3YQg8W?FlfVXTZfqj{IZb8DR7m{ny3UTR$45b)&t z7mwZXS&Qw1q=9EJ$|T_YqTGmJ*rd}?k9C+YEoqOQqkP_~_ zJ#LaFOP0jmGL%>PifFBG5G5j zhes`DtwxR}>$OLDG?|1_kHzUcgb(Lmi8`5lB0tnOqp4nW#v6cx6_J2`_})hN!=c`8 zLac$U*dz1Tmi_p;4WCP1>22gKIbds|A?fdtOwO5PV3;7NpiV95)NoHFY35MG=REzv zxm-|swY1y%uU*$6h$TXZ+|O!7ZfWf&joam!tBO(Q+jE^viJ-glUb{BuMoIk!_dL^t zN@r-C=%V%uv*q!7V<9K;b;n!v)+z%%DLXNA;*Z6=w(h+lqdCO{LT$>P)A`ePyW(C( zb8zJ$Sb8=@;w6J+UwU@dvhKjFBZ?~WYX94E>RY_C_>Jo1JRENKBw*5m)EIKU3wn`g z+>R{fY#8adN4p7X2STd-C;)nCf{d1n?)UdZt-QY1`>Le?jS}u3oA&_iH*Te8zWkCd^Drpzq8n(`?{$c? z|EbskuqYdLYCg>8)c?HJ<=|zmTDPv3$ z$H|>QwvA?2w7rh4q;4RM<%!OXDo%(%&EMECRv`+^_TiFbiCB@vw*MN!IV zm1~i2o|t%3KXj|PEPoaT^j3!ah^7hRI6jNJ*3+32WshnFw7we(*LuU6Ug$TgV_wfu zUgcou_MY`u1RC-WP;2?MJo96n~D)7wI`qHTcE@YKlqRJ@vb0m6uw_ zQMxY3R{6-@wpdrl!UxE zQ64QA%GEzu8qRYNQ7K4ZMRY~e@#Z`xO#Zh1OSzMfI?sOqmS_Is5rsHOTh3!5%AId5 z-vw-Yx#lZji~w&br?rfoMP8id!eRrhMn1>btB#{Kn5SwiURm{JwygtBX+?PT!CZ}N zo84!6{|u-0qwwVu?x}7GrwpklKEY-r`#3{oY{boF_)v}K%GGjE*j%H|oJeTw#}>B;)c2U1JT8urn&YVN>bhmfzPlU0033!xw3Cdku|ZRzz`h?9m`Qph z?!BvniLna0$y#|@*h;_`BH&71f4tGW7yElfISvbBlPw+9BWnOI%zwVu>W$3Betw*c#(inD}r44Qn(&omqMqJgq z&vOT6BMMtSoE{h(d|e<*74WQ+xH=<4sD3^7t$Kz{K08}?N@#^y3S-Jdm!l-39g*b8 zU{!h+e!TL?e%kn0&G(?A(`{@0>9DxKBXm?FaR^6k1K(Uh)KN?&hToIKJhwJO@m%*O z=l9)4^f1@(B!J8(Cq8D%eGM%s1dJ$So}nxb9S*yp?7Z6?mtO;_&Yn(H+U0N=*XZL* z!QXwpITU*;;xKNkoWPZLDPYyjs0mI4fGVv3{!G$`TDP9uH_NLtQ|=Yd#_pg6Nxxf~ zAG|kV^P>D^MxttdD^u9vL?Nw;3E{rh&F=WSDju+gdP5H^vHdl5OAOe+8)o#v&jZE* znx64ICUfrs&X4*ItyQeYz9b5G{w8EMsf*U|a-6Ot4Q=(@nKamITBi@32h@x9lryYQ z%5a)TbRK|x#{~!(v55-`4}NYypI28-i>630c#?!XxyX7_;gpnVkNU+m<+)JfGH3{LS{K zw#LQbYSBICrT_%Lgf4Il@qQE3_SE!p2)M&oFvIC5ueGNxdP;d7=4zLj%8SHH9cvrN z82i^&Xgt5;xji;vDlNvlD?_gDaK7(bB2)1336Ne<;bAH)e-G$WUK0LN|FIbYxE%k6o3oXZT-cb1Qa z-?vIVw#N!tPS<*JX!KmM(-|VB>87jMiB%(C)-q;hmS`Iw9v{2UUTG~;uFOn*t8hCu z)MKW*{KYs`zIVYtxIR{(E3cfyu`8+pVHHCcFhE6Cb7F#J>Ch=@1BX-^{dTP8^EpbM2v@$H=bp?3so}kpa z?-T3Fv1+8QaiAvobF4ezg%uY^WtTvlBjoe>7!ctK^2Jj)6TrL#!S64olz)3~Y>*-| zVO{r#{WTsq{U)_+bDjMyoadIvakyq=qVvvD;7wxwxa0ID7AYszUUGFx(4^#!^KW>n z*5`i9mukznw-A?6jd84McP5tgckl3h%nEu-&M<&Ck{?B(46=)7FHAez79(S-+y;+z z*Z+QEd`LW)s}u(3MV8A3dp=ne8j{8&MLyPK3}VF9D>Y`?{rx>zJ;Q9Gj07tATpG%L zx!<W2hM<9ClN!7w?mC%k`UGze$M){?<+vc7Kh((jAfMwmB?M zE$mm!X`-P4jnYfED{l4=nkmBKBpvP^@((So@@X1c2h& zHA{z-BQSQvtzXy{wEg5?HoWKC%y-ybppcY>1SaQX|Be2#=F7W4$s2#XJ#Js~6qxU< z?pD{=vKIY_xO&h08jqD)+#7mp*;8M5W3;@{;qF?G(^BYx0HD#F+rvVr1~lOpRaC!s zo7u!zZ0c`*hAc|{0xmkvj&z!EqwWd98k^i(1re^tl`;{Tk{9`zQ0I1m<&4Q(G3b@V z`BGnCDV4tu1ZY-{e#X?CWJ=ccop!zLoW$DM+!Sdjh!EyIR2-s`S5Cbf#`%`!l_@x? zg#rqmhMx=zW+#t+F_{Lgb!(faD`8Jv?8l4gEaMAY2VN0NQN`smq$?L`2k8R)fI=p< zNs%WNR_x8$4E)D5<0bCCh*v*}PY4pY^-Qx7$HeHj9$B4F+5^u>LK=#anOin%LDs(# zl-dercqdOlm3R;F>Qs1z&|lZQ`bR`i+X(T6$O}3x+XO)9zR(6bjwt${E@-z?U|f))Tx_s zjf)I+;)PYtW*_h7z3b0z=ATf}ybk$2G7{^ppwP?<@@lsXIrpXfEO<564@6-D69;7Y@OQgmpXlISJ&X zKG8)>uX>(xqDcv?KXrtMrsIZdF>XMG`TIUEubs)#nHV3WxmxgyANJLqVTfjz zs|GH^OPI5vPvlk3d?4G+JEMu-bJTZ_w?qd0zt&RmBlDD#U5!HTR(7&YlzsJ@t!YX!;vwLp%FCH%2Q|gwjNL%kAo|ZD;(-$uJwv;%?C%9 zIr?YHo(`=de7T@I2#M$|DyxdP1#^nH;!6G2z3tqPcH~_hIf89=1Bs9Z8!H4)I^B2k(cX z0uIjUHwVkVt@LIX#Zu1Jx`&T`(E)U|D5eo7yXqfs=Z3EHKM|V)A~y0$bkstWqnmID zy3&1XbEdrU!}(FPRbQIgmBd9psL3AB#nQ6^nzZ|^mej2hQwOH3pgK8vF8#sdhw5BE zG&2D)AZe!7O=X?OS+UGi@;HI~)NCLO_wi(V&r`PJ7bjxC+=$QZ6fRq-<5!hU7zi;0 zOxjzonyTFqu7(7U99`s|rGf7KX5>Kkv`KxP1WNIm?O809l< zGPe#AF^CmpNg8Hbb@L;Ah>nBbu>acZs&`R`cKtG0Nwv-NZ0t+lfIzPr2x$kwi))5) zbNKTJxSKE9rIr-wwW@h_i4NkWox%BruAq%5GX?7>6r{VwaKT!l%lbUcc87G@;{i`dI_4V zLIE5Lw$8(i)+l`9qcq{|V}-B=6Wkaoffc$8Dk}ayb?5swE5yy&^|q%x)WY_melaob zOFt=)5fIo^WBRD`p!A$yeLCm%WRc6_l6;vwAkHWIy>Ih<$PHQKs*j(yUj3L(A_v(W z?-}oF=uJl7=mv0toaM@FRrnAT0J28JWnwR-o|0Gu`}VCw~TK1_Acw z+~X7osiHO(SnSPB4eihEt#Q)b=w;raXkcplx`0s+s6$WTM&{$HaX`aXh5jHr!qSK{ z;4Ky@4#+wf>aokn><69xK-ucgar&?0y=#H~^)Wje@cUP|`ctS$Zl8=NM_z(xJk|S= zxHtx^+7Jv&)(U;QfB$RYzyuGo zsFz&1?yuz_?lAS`{jUlxRJFzF2aVfnZl4yX8z7a_)*f|CxBzk-!%N_f&<8|6a2O!a z>j$@kSuW^HUrUT&|F4;;^d+;jB+E0AR}m4ofHd~zo?4nVsxy(xKmbXD(jcXy3k=`r z!n&3X5fB(2(*0Aoxd`2}dHc`h1!HlsN=sTdZxC+)hh3Bs@K3aLeQN$Mo85OVfQt?y z!hY6v-VH$qQcpY^3+TAumHWsf_Yj)gf%i4chyoMAv2Vb5)P2+Nl12}Bl(Hy!c)%Sm z*FpRtm^g?~o%8SCzjyVmUL8ooI7NGPav4-8ZjBal5Ad4(=SfOq;>EN8)1{S}T6bV@ zx)-Wj`L5UUHP6k>FnTZ(0_USQuro!Q)mZf$J!MQFM0*cpZOWa|)MVD@ zF^@o~=_74^gjGX;i0RFoK6fz(>wkFK;23T3^#igfIoPVgSX!Qnr2{J*jw7=Nv{r5i zxEc-Eg|LzV&Mpld$6k$0Dnxy=-DJ3eh-^Kk9vMik!|K(GItp2j#n*9qbN?a5gEa#CXR<`)x*sAZJ9|&G;%L0Y=*}Dfk4O|IqGw&`Zic7+OTdVmbJ7 zQT_K+c_%#y9FC15emm7rP{b(xcVk_{YiGvvLVNNpzc1%2`tNp>#ymi~0EZphh!_(@ zb>{y2{+4cmi(;2V9(3!c==`&wK)n@mhE~P4`hBA*4U@MV{vTf!5j+cQ{H}bgxcdKX z<0pLyh{DbmjZ-%#TC@4>{{3Y>axG416GI6B3Y)}#KY<|N{8#;TZs)aw#Zbz>G#Brr zCGMJ60~13CJvG6%f14PRK){)0r0;Cg*66bM5^ZBvYSzqC?L1$_x32mxiNg|G2-=%C z@-{nKF&76M_s$G(3EUj3cy0V!h|I%^U$ zudc0_7XuApJTSBANaD}>Z&ZZHsVo3*sW<`aUO5KP33Rp~|e5t@INw#>QT9$e0+k#Un}4J`v{`_ zOH-glCfwH2uh=&HNZ?=c375aL3My)&gx3X`Z>kXVwEs8uS{DEQQO*C|k4EBTLpV6L z9_(y@Gs|9G)N2!LFvKa~>(e?u`}6V;y+bPaFAWR@xY7zUxPqMA#w|GL{dv;K1Dh&= z65oK#dtzb;qM=y4YjRL4tK1G&((08zw-aH+e)g}pYj*~3u9K*sD^b1R2Xf3Y^BIKh z{}HO2L;grFR7wW_k8US>;$mmO{z0~Kx)*$6Ly~O_7e zfSy3`CJXe1NO9w&MG*jFD`bpvn07?xZp2TH7YjauW>)txidCn|;I5e}=+=ve-0q1} z`l8*_mPUL6vFP}j{65$cPk$B_Dy#93Vh>9F4K4S$E{9r$mJap7;7Prg@1?15Tc(qE z)Oz_EHc@5f|KyTM!DIh3mxOM@iqyZ#uZ4gt7XxcJUyXd+_$vyJ)2S&Mi&hP!$6Zc8 zwz2mAXP$k<46^9$n*#C>HFS2&_)pcrjjlStkO#coU|(Ph0aEju;B`8w3XbsK_~3+n zS4QpfQ<3?}txY?E|Fd*_biKLcA1=WEht&M}W1oSJD9Y7s;Hd}5HE4X)_iQno#s4jB zh$$Vcxfz`4w5Th8_QP&wx82{u4}BJb6Yd*mY31P$;N2JZ-g!s+&`mJ}hn_EH6^;Fa z)F=6Z;5Hw(8tZK+Zo9}3s$)H?57=IN;Vb|r0_7>U)z)!}#<6{nY_9;b(Hut@vwG%&c88f z8QoTJo|hu0gaUU!g0+EUy)=jla-b3SdO#$aIPh~Ek>yY`typ>dwF;=p+w zb+bpK&9ObXGI^G7XM#|w;^kfR!;g_O&LEl(I*R%5(EV||DafNFP9`nm1Z~l_`rmJJ zni>N!tA#JNDlNnmw8{dyR%n{(o6kn%VBJ-*I_czXzOy?QNhXzDLPxJcz+*`B@c{mzD>28+vtRl-1@!X?e9D0zD< zLg#ffHQEpK<(s}9GB&Hu=*{7?JXWn57Yih+B2Q)IfGsoOQ5b;=0=~HlXMh$kb|UqA zr2Tw=$Yn21FkhqZQe#c25ph#U1Kp1sSbX2c(J}==B^cMbZ~KFJzdX>)hdJ>C0Zq>r zAN9nGl;K}jr4pJYpj?6VC68^t_1LdoU*$pYnl%BIr0J-TEAL#$8(jT7l`PW{Z08k9 zUj_R2yrTre5YX*HwO9FhBGo=Vh)Zdz23UV5ei}umI^IMI)qH!b-eC?kug99M3iS$M&B8-g`6XxqK3jLH2ddt(%EA`QOOw zpp8Av=cRlE zPzGH$?QYqRX7zq*I6cv+0?I!Pzr(<^p)9ey%$-p?t-hFT5p5C?zXN%?e(#-09<&w( zR0b-$VxHDNw{+Y!J-D8WL^O{+W#h5V0o$Y;n{ zqmw00*M0dL(0Vju)c0+OJjwv}n;=0x(oq~5S7$}t&NFf+gb@*@h1 z6!RZgWg=vj5YrE63!!lV6kU#;I&e#K*%#+^o(?SACfm`LwS8KRMEv0Q0nxKooi*rk5eIZ)i-eqp<>paf zl*VRn>#@UxQ2&k1d2bYw|2LzA4G=O<=!XQ=5x8iod22&s}s|pEIU7Fio z@eCA-k@1!4n`^$eO@G!yG}^XHg3J%PGGNh(b3hQfkt z4+GNx?M`LyXS{;!ZQGw8m}cudlSl1_pPPl~Kq~Qyx72{D=mKAqcMb|ODKx3h?Au)Y zITEX*DsgI@^SEy7^#jCacGz&aC7V+GgAy_B!PmFwMPbXeZpXbkyBAVMmxY(UYZ`V3 zza4&4@M}U`m)IV9pM0n?0s83va@x<2FkRXHdRxSZXVm1IqaoC5o>Xt~Ba1dfBCicK zI85+7^w%9u~!zX&P@);h{&v6+~eyt9gHQXG} z$tPMMDWob`TutM1`Y_`Tlhn$VQ$o^mVxAwaCj&=nx>tNj6W%Z8OXnPMSLcIJYM|-H zJs@#WtbRi(`bt{NW1}FRG!(l(Rak|McrrBHmI-0zSNLYnqy?KF#)Fu(MDVx7-VxRk z^WMuohqE9S<$(u%gb+(G{$V|AKqCi#Bv;!HC<{2AvP5XHFG`#qd;TB@Af6}_al&K=EULp zK$(RO1a%nY)cv3}e`#)(FYHXZrB_B|22A*lF$+2f+nKM{&?7-f`0L_J=|AZZl51xA z{GL}7i-Jd=Q7v8gspeZ$EVZEFoX@h_P3%V(@(`O)(9@Ds*|HEWcCqmF-WM;0)+Z0` z!*jCEmf?1GQ-{KOGZ5XwK~{&c(vn#8WRHr#iwB!Sf{!l9D}5_B?VjcEpHZylxt9A{6z8(pezXhNP3+dX&zG1g7pL^2 zR>(5C&A;cW)q9nuh~<0h_h%iWw-oRnzm-|-bIzauSBB?>jBm=htW};K^;!L-lj&gj>*e( zslXevB+)R17^+gcoER_P<)2?)C|1qYo!uba*Z4bq53Q^I)50e~;tugkoOa$Yd9e~U z*byg$^>E4Tmf=f+d;{rV=G!<2#Syar$t}7L&VHSN2hWTSYU?)?0>qxJF(s7e61hg} z|K`vs+8h>@a2fkD;o|rtjIBTLh*S5P3qz~%g2}6JT3`R212%1VTl(pb3t7+F*?l-v z$iIrH^@ks#yn6AwZi$Y03qiOw!nE;X1Ci@Jg2LE-}tPSnjQF3L<6EbN%HGR zD?Zuth^Jw9!+Fkc+i|yyFGS%&;L(lQ=@oz38!8!o$DY>xNC62XaOoO9gBBB+58V8H z|AZJVY7_JHHJKKk3#od8hr_cHI90)-)pR+smAfF1`39ZC|3U1JZU6Lj7!gcb>pwG! zu2Vj;Cm|*p7(W^i8LsgNjb=96W=vf>P5q4pEd&_|4_6nOp%Qd?38p%m!=0PJc8w0lUgAL~24!jkb z;}2Ik6_4)-Yu|1beEyMWW)h3gnP$n3*Q6oWLIgJi@Alkv3l~)2>2_vFTR4&Ok8pgY zm^5L}yVrkUJWi2j#M)ZQQ{fqkC1Hw)29Ml+>Z=0A%a2xt!yH&|X{GMbiFv+t6~OhW z$(nnm_S!6orc7&RlaqS0EiLgNSU2ePZ)^LjTtu zSY+v1xx*y-Twx>Gg-^QZf#V)7?8j$dP`ltQ@>My)mYCt;JxxvI@d_X9wXe{5Q+A!Y z=&E%~h31jvKz_TfCKgd@`|&U2%axp`F%6*QJUCxx{Y|~o^=BHt3CP@w;;&U|?gW0B z|M)2={0eU|1XNwFC2?Zisww28Uqk6G>y`#u|1IQ@aR0=ZG=PfO7Lr|ylLGE-$sT|hIdeKt7`+dC48%i?z-&+FrC)a!8 z6~ZJQMUx1GhR{I#XJ>Pgbx9vyV)U_!i z+JOTLVY_uM;Ri41Ty1-5_SIYlD5}@##t+XkCDC)qG87l6RVi91cghto$e8&6D4s6R zQNN%$)8v?5nr-gZ5rs8_7b>=qee=a^olb8uFT)}1=|ZE;F8d?Hl>Y3%JN`!I+mppn zAw=}>VuNq?=^f`t+#}iPmQU9^!-D#s3vP(Jh|0jE0!@mnHwXsVJ`T7#$Loj5HDiWj zzx^%5Q|TFy$>V6a3*kGEPM1f8x+pZj_CLv{#R71DgZ+^r4JG0od0%qB}RS{ z-0vv7us5?WMG_heJR##8(pszq-*)@16Gx-5oQOBKcu6CoHs%|AzoAEL ziHuGZXfj(ZI)C1XRZ)BNZaIN7bZO;Rh7sGKixwCx@_~{SU*B=E!7g4*;VYu+Cw#FO zqp43F0O{ky`Ts&AG6Xhm^s+U_ieuo?&`zB{e-r1o6<*D78F^up@+g3nWb0!T`DgT? zHCQu>o^uhFdxb-P0Zgw8lIavSbiWv{zO{5KDK*+}m%+6g{`}tX`*zK<%aS185jG6A zKexs*V6$1s0R6*$i~C`6M|q79bv0N}wmlQpoHtP*KinvPvj^%u{-na8r_qK#!f|b5 zlUSOEmV6~wMx^R>`}#|^Ym2di*!WiqsVtwxEd@80o~z=bz^p59_vp(p^@?y>R=^s1 zymOX;ABw-!+H_ZZE-Pgx!`hP~WD*Yfk<`K^Id+v{0A?V$`tmswrA}7YYAh1}nD<&B zeCW4C?E5!I^Q*!49Vs+N^A%byQvRJz3gDXN7$K8Hb>-w&>ZC}D1*UWlGsD1X!S!@U^4jDoynTr}(hL831bZ_x`Vkv~daf!2uj-S~SUKFW+dNR5wo)7gEHc+h$%_LqiaEYb%dXZH}AWSOlDvzfO}mJ{C5 zdq;f&Edk_TNCWxMjtu2`o8`yTYE3w3U>;7FHFuujA*9b&PJi42&Iq~c@rD&PKPhIe zH-N1L8Y3gL;8u6;lFZ9B=kIr+7`l&OH_X`D_x;B$MTPPp)1Lqbst+G<4Y(1Uy7$>+ z=V&;9S7XA&aNzM+@^G!CzukC4Sf%5{Txk=_k0#3Iy^CKTuZD}f6Gls)vi(Sk$Nu(O z+8D>=^{M_-Ue!b_((8X#fyy8+f5!6c;7U3lF=-I1%a2>7dK-xcMhR0|(MZlq&+Yv- zxg!*?_jY;Bh1PVecR(4uBXa#?akKKe%4~pFB=zPz^kZT3oeRHYbIDiF_T<~Jx0V3HSd}ka%ewxs>_GVQU>lG2waj){pBBbS6HhUvv3#}e2u1q z$W+)4EFuU^uWZU1xEKbEK0*v&+ZD?2fe-v9vay-|O`7+;wod237BgwOLO4uFE_c37 z0wO|{i9Jc<6t2(GJ2!>L1YZ1{s4yRTrkDBi zHcvUWg$?~u5s2Xh99TOef)ZM%=y&=yA){W(8~Kc1zPUDjY_iHkYMl%7KndS(LbTnTavm^F1a^mqkCWB4njUpfWpGe!IH-4hu z0M>2cCUBf*7M-Vb;+64Wyj+ih`+Dko_zvvrOy@jnTuz-iJ|eSO%nwltz3@Wh85xr7?U_uZT@H?^y5{ zRqee)&(VobHcbGCWAE2RW|Py)vo_*8_(vU-St`GU>{bgaRzWD!$FcO8@E@LD4SHJx z`^mV6Pi=e`J36I0Dn*83%@D;}o7BFQa(Hj9TxvLHy>Hx10PmsRwGwfx%w{o9du7;M zpmj&&>ekS&1om&0K*DmTasL^i3PzdqIs4PP(8}irX&xJs>>F1=*z!fYgmwK_M&iKf z&U@h32}CMmKs<_z7Pb`YSE)M9))hwkoo;fb3fj8nH9AbFQ;XYF(jxbalu`u}6Uz20 zJ+|j$LCY=oG@6!Q^|M+!2XGHfmhe5=vUN0UX6@=Es6-OPY&e(pVEFL-s6pA zrkbv|>5OPe$})sD`QmV%?N+0o3UI76IWL0uk7%uxccJZB6C3@T<9xHY02GOjw`J3M z=4xLA%|NL{QbM)2uT@zYLy%`Vgmj3~9psjZQl>+@%e1&lxrAafn38@QlY9sfQ? zj2zT3u7PF_=P`{?0_ewV*&abs^PdHsX7cJVE+D{_A; zQK8i?w{A(UB&Bv7?SvtIp zM7Q+~g}*3O?SPql>0X!^f^KJgJ#G^w0`B9qKSfxvWBwO=Zygm?_y3R5jkI(tEiDa0 zV<25hmw;|BdjE8^`4ODt~0*3 z0kh#IWNJS2BMF_SegFf^MHZSI|Cji&^C7`vA4zXFaJ?iWoLGP(s{2Kv> zBKu^6`?X&v6_=~@leO=0+3a=yyPAaErevZt6;LW3O_OUwvr#IqZaNEIzw=TrhhEe! z<$ZIoU01yQ!CIEv-9fW@yV1`5Cp+8H_p2Ty0#%`=>yjm7UpZA1@wyNJS2e-ptDEPX z_hhH!;IKKvi3&?@^Dm9;Xs~4!zM8bldeCM8`rQS!vVntUfQt7S1SoyI zey0EK4w!?g!IQ!Ia_B0Q4=_z%L=n?E&%|l}RfEE=bChHRk<*uvde=U|4bFWZ_LXDz zcz2Yy*h>G5x=igN>YcKP@Iddqw8UEdzpt)>@UEcMNN`A=QI!Zm+rct&!c;R#~*oyi5viaQZ zJFKeB?%wV`?VK1|dE!3zr}D&@h9tRZQN(-xB%aU!wBX(vS18EjbwquGfirtamLKCJ zZ*}nC^Wz(@r5ITJ2|h`Ga@dGO+iMGs>oBLg36p%p7udSZxWZ8!jP=KThPp?Jr` z-+xP1TpNm5Q%i1`*4~ODqA}awR5E@amp|X|pRT(YixV%;eR`y=0~uoq)y%DhKnnmmOz%1&4(z?5QC*2;It-S;~#%r@Wtx~_D(pA#-=ro8JBx|HR7p94Ke(xW>vU30*;4M z$PwQ%a~S>ZqYe<y!F)Xq6&DMLBTiEYF2KoC1lrxyvKgN{ zU@@ImT?C5>Rq)G%lDferIpT9-nOK0 z2@&4#Up$RwAgb}&h<_6aQH3O(ZcqQZ%u3N^@!Meko=9vh2e{*DKXak0XC$c^aa7%X zlNw3AKR!YGj~FEl1_DGk&yKS;SG8YVi_>~_@$1)~3rkx!yaUggc&u>fg{VD?XB>B_ za$P!Us=~I~k2goe%-Q}+A+fGMg+4$ZX(DW|5mOi zkp#i0E(<`iNZj%$4I!l))`s*Dr2w9x*N8IEI~ph4d*e6tL0<;|4^7^_K;WYFc}7R# zfJ30d{;Sbwvr3Pj{pXx~$gIzn8U5GnDCIv1p)Wp8d;H#qrT{D%s|s7G?#U{V(`0#* z*XG5Skf^$GCG4}ii!rQ5WW^pekH_`Yc7dqdJQpY!!S?&^*Q;~MjjAR+XNg%yKQ_h+ z`%5#$4A?Z(;V%F+tb6Yo5KCOGkQgJUKwQ)r6B^OQ)AHw2VY*HBr#YMLZvfc|Zz^|R zorkS>XAuZ!(7PC+1WSL`;P2@$jVa3ZxZ_`txBKgDYYqdjXIO55y9!8yR)!L4l%^o{ zzPRf&HO+^*g>mQEx@W+b`|k2LimZe))|-zyne*qR+IS`Mcpp9u5oVAaJiikWhzdcj z($WKmt5VC)Mjg4JZ!F~2^7GqGe^Pb0tv2>==}Q4o<)h(Z+rY`r0e!f3wy;HaGAqC3 zFM0B1>3G!Tvip~x(R^n=5g?*ySNgtp{?CATl>1B>GgkbrcrIXkoofEn_iBVC$H(i{ zM6J4*kz0~0oCNl!uuqJ}*={}rM4&{)uGo?y(j&|v!NC^ErJ{W;7roaIXim`ns)BKX zeB*0^BBkCKipjZ88osBfsS&!YPp90Khucs=F#h?<~7@|Aa^h< zF&f>=(_)^!I}~f7SK{M3iEQ&bllNbw&Ia$Ro+&ej*~5hhvgnl!4LZ#3MP`t@0lw<<#u?_Xm6OY0Tb(&<_#_GWhRSYoa>&V+<%n) z$e)k%+2TFxa0Q!Lj>eIZKU4}if9Pt^ZPP>yjfy;)O5ZEAfA>xQBpcOuEoFT9&A$-& zZ^|3q|6}D%?!T2cTSyR$$oFQJoAI7y$Zc+VatEoJo+)9HD>=YIIw>i{a>8wDMJ5i9 zQGMSOi&GLhph9yBByKSXyszbza*s8{MIb7Zh*f?IjfkH?M%Bfv~?rC?P!9?40#2>rCIHy6p)Vu`kG(;(uBf^m=U9 zf79si*N2_Mg+d5$Q~6w*(~jO&g)YitZb~xI*mb{ox-7~b*`uBPmRnzu+;``@ZU}HG zjC$j-_?EKMOT}(k!3^~Jl8H=7qNP4irGFj^e5jdQh{X(4mHd`U+9ve!k0SYxr~UAi z9|*_2H>;1|TA^E()gA%)88pGZI}N)NsS#|2-HG%!iuH<~|L|0p=);a=kEB z?2@fyuy$$os_0hCXVp+S-kLPF2(D2}IC-K1cj(Jjvw$w&>&xMc$?=KYBSVnpx2^Sv zNl0asU#nf}quZmP)Nc;L4db!+Xji2*_}O*7n2IkOre9=4Y935?uoL(Nfz4QWe*DX~ z=h@rlgZQ)Vs@y49?6;*U0;Yt8<#M?6_fP( zy7A6zKqCxzaK1GvlL31Oa^&Ji)9mo02Vaff-OH*CcyYr;Qt*!l>K8o6ecDwR$%qy{ z#)mj>@i4u5o)5W#ZYP4x?s9MUAoI-EOvuo!+R`5@L!Y2`z>aeT3A08sY-lmF)e`rT zv?1mkWLE`XXG|iCQvHX$&pMvV8b98cT_xQZFDc6Tu!P#GCvPK2mGa+w+nqRBY-${p z0u~`0Wuu>H>|y64dQAa|bnvFvW65Lp$sa|S9Eul@^^VcxKKtC@ljwmbKe)##5|ptf zp=+WQDL$`l?-0EY=Y5Bm&1DOhX z@WIYw)gc=zoG_7sYu)MjlvUzt?Nofo+ZaFZNai;?9t;#l{K8=j;wR?FBYQuTam9nY zA~yQjg?h`D$B8*($#F_=E*2+~J@|$|)5hSW!o zylUltxX(8Z@f zKR}}30pdMd)`>yy4pkxX1j+IeTT8UQ6oJY5KC{q9LIfK%>_`0SyWkitzEaBNn@&qO zZGBg}J<{>8EgAi7I|v-wTISyACvft67;q&GzAGYr0U|gjHHR3rOg&<^E11Rwpz{eUEGMWFB4E6t8 zG9*8O$K67=-kt^efDgt#1xgmrzX@wR@{u&2s4`w`?|N$S6wuoRj~HhBrRAYM9|_kR z%9y;U@?k|kqsL@U%OkaZuTT0nj%@#EUHn!IJ?eb;ABv$PV`t95BOg~H2~+qog0gbc z<|5q9X7THjS3vNhB*`8h;`v^T27syPW^0w{o=jdeT3V8OORa?}As0>Et4sZ@ez^f; z9RJVMFOCm2p>KTm1Hn-ofF8%!2Py1(EhXje!F#;@P*EEK(qr8?f%4@VA6m%-hja7k z+gRUbv-_=3noF@Z*$e%xQMw`Q%yk>ca!k=*1kiLD4S=TOBL3>M-E;)w5d!p1)!1k* z;{wn)p}!_B296K3Lw~4`wBGyw)*i{`F$TKgAT>KbZ8qhL92`nA%y?9%{-gjep;RLH zAv7Cs%r9WA=P@1}F55bGxmZb|^;v%nP%qguapnRJkA#~x<|qFPYtuIr<{Qo~ioV=G zKUOrDKw)LLN_5@)_i)76Q~(V8Z{oi)m(}M5Qt6JXa%f5gICEW*Wcl>+t`?8$Kx+0}RYPOG8~S*zv6wY~ zY3~n?HGR6TDXNs-9f~|M2HK*h=op=Yiv!$$N+M;L0D$0X;MLDv4>D98)rgDbfKVaD z0_Gv62E_=V6*Nl$knQbSmmf>*nM40nw_^S^_q73ffY83P10m?TFXws0fzo2!?W&pI zImk&&hb4};f3W#Si2@#r>>?mV)`DAv7?c66MeRdnZ7BH)I^3&BJNG3uuih=NGrw;5 z!60FuES%Bp?@*#!K{(`CApqa0_u6=F1`?$~OF|G3{j`JF0Qh8J)0q3u6AZqj3`8)j9F;ncKQlh&@n3EF zXJ~+aBmK8>Ceqndfc~$?8a&^jDriNI358EbO{L?%MJ%`2SSTt@(?`cxlM|xu|1InQ z&qi!6*niw8m26miU?To+jmS0fWP-m%NpP2bApPJoVlwmxHg`z$)-OrjRnknO!+P!C zSJti$^f?R^6nQOTY2r?Lle_nT zt9+uOdV{$TAz*EqX44ff&GUKiYd=Vxu?GQkdH}5~wrpuW6zyd~i$p^Se~(|5PMpWR zeCQ?WVDzrg?Y3}Sdmuo1t`Hnh43ePDQfpRD0oK+Fvhd!4@a9oq`t@ec0}Zd8|N4yE z-a8XD1d`AMfWtfipZpxPEY^g^+i2q4 z8kP)0$J>Eyc0p1`iED*yggBd~5t?gBGd5#GJ;&y#oWQNJ&u>BA+jC$$#s54R;q>aJ z59;8nkf_U)us@)sbqscvibl#WR|T=FK?T}y4>Nwc%OA$#dG9tMKD7F_gwr5ZVy>jE z=LBjIQS*>%?yEGf1MSbppwlOSYZrZ`IcE~c{8kes=Z3YUz+Cs_^uXSK{k5;%LTlJ_ z4mG0OU1D+J>z(SCJ*?1P(39Z@=}(A$5Qormb^B$E4#^}-_gRATzDuax$?i_~)1n;%sqvQCh_?}k83+qWZFK`sl%9zP79V@i4>`mxFDlHcbzhU8!PyFI>&q;!$8`+I+LAZPoKm z3bxI@t)9fh3%X8UIEz67SMM982ru^@+>x^mGDt5HF~5tb3B%+1BvW4Z;%BKt8&3G{ z-eSkW4~N`h47d*f-){-`1)xsXzXf==dVyii@khs@wTA50ujhpB?s-ShIN|kcN~vDP zQgFWY+871ftot<0fL}Uhc%$-;WW$HNPg%~dW_`_tk@*G!zYyPdz&_ui z<70vZOP1&>^CZP!XO{!mkD-Pliu8~8skG>;rAD?*-3$5x>>k>uKQfjFj-W#$VVdZ- zNg`6sPxF2Lym_?}Pto0UEnyXnFJKOO0YrMv&rd*-c2JDcA|L{Kb@i14V^cs%z7ERz zdmycV$r~tSzmp0J(-TNh`%>5=;x8{w4;u~$Mq=nW8qZHyhB_iPS!z9j|8J&3@RtBN z_5cv8$_^~)hUMz!eF4IqDeYO<8j&sOW>N349KA-dC=bpkz0d>LECPJL;kz?Ia@P9l zt^z?a@Xp?90GhxL%AFa#R^+^fA6^73vX53i!SboQ2*wXXZ4~A9mzy_ujT#o~T}MVZ zFLx&%fY3nVP7$Lgm6Q?WJQon#?u3K6z}>E16cG5`457yc9RoG6E0&PKR5S-ZdMc+9 zkG}U_m#X}t2Vw-JL6XDEqC3EL2r#fWIr*rS=NVF#`R&p6bogXXx}fklt8sbu?pipCVi=CC<% zqgQzJoyXi-@&1Uy)_4gwL4jhXHFqp>2rLP%ew{qG=3aoWf|x&Mww z(T-5ike%2yDmUW=ouAR#Xu|kF0#YNsJ#&y0d2`@O!ZTXvsXGGB`3tyb+yRE}H%ZN! zx9NY8*Tzo;o4JQt-6Z)npAJJzSPV~Ey~7M9&1l+dCoY#*aH4HC;rJ=;Gz#nA0#;6? z{u>~6F$g?+GGR)=pbup_BYkG@f)Gi$NqP)>%A3vI%Q!9NXO)b#J#H#Jdnn_7VE2oR zRAOp9w0ReJXgmXR4=?MBb09MsM$!5swoQ>o!Odq52syv4bus(?YpfwBc{0AkD3L2C zTVx>7R0vFUhU@sH=m#>_Ah0xUX{%8eU`wqIzW^TOMly$Ut z>COutcA@5z{I5;~S;|r(b;`-x^DUMgffqHp2;cL~U5{i)@RHjF+4myu$lYJ)_i;>L ze13kuL9cb_CF*?FJc7@HwX|qnA71cGg*=~186+og%8=NGhG(c2Mc+}!KkDU7js=!b zgW@Sgtgop@0ckS_`wADSA4HYDlQWV~IZSTX^rKzel?fn%7*oQuc@Nt2)7I9Nkr{1l zs4iMd0y*0~l%EA^hxpo=$VPi>JSLNUSZoq3hwZYyboludOT^-vzRnggK{31;ZJ zNUJp)!T4D6`aa2M4_jywZK+6QK@z(HxpH{mp7~heJwt(Cb4{jz)nAgzWQOWrcnryC zWuwMz-vfN&F&V|o);TdC0GMxL(aKdQ^Y4@u!Ax*{MJJa6jo>!1#fS%3?qVpM-9SW1 z#e%(>T^Y+fOtnRbvE7dJRAicjEAPE=to+axc(E8fo_bHbxWIB}h4-wD=oe-0omJ_xE_%DfWtwSKX0i(GLjsEO$AsI{=$Nm#|aXNqF%qI4aa&^DN}8>BM7?2 z$O6@1r2S8ual+}tnf-lRF48cus9mxAb0yt!w0eh89{vH@BSrZ?3$)d;R8NCNqI%nL zN&&JhgZVTm$!C9meM3W5296yP%C^A?FXFIMP< zN0Tpjt4u@lLOiUWJALOolbsSih(@)}`z`RES=*vBYpuy7=oodhVOi?QEM?31OguoK zG9nS7fLEJf=%}eYOlD=suzXYX608-1YtaS1wL4-Fv_S=3hQ3jdXAc7IwbnPLNhf(2 z4#KpsSgw(XJ5D+7MH>s$=FbB{HQps)@H;uI(FHKXKURsIZX}roZ%WM1N;#ar)~TI8Hja1`mv$SM z%H##Eg%?7UeicCzzV?{&kD3h^RtsU%bI*Iso-eWx*uX{r#)TU=Mi>jdty)^+J$vS0 zTfo%l;+WoTM>=G)(DQa^{+yje#8J7r!#36jU$(U$bCVVe+Xwp@cH2`L{L(>dWj8-0 z`}T;o)hGcTd0O;3Yb}X27U=u3k~e`@oo5tpzP6`Z5ty_&@M}q~_>tAobMTmqBpv#nf-LZGXUZ_Ve5ns;TP(uOX9%r#!?R#ESK6q^{w zVWQToR}ZjaaL#m~u9W=e86>tJBV<%&Ix+~(+umMDCFzJBvCKoUpCJ?RK|}ke;Lo0b zYS)#ay$jnkJXbvE@VYW_YqNWO54=Eoe_Z|N{I7}@#CNuxv(EVww>%~<&Cx%689J

#W9?FkJR>v1tnDZ9DMNSfC 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%0DGdVygAQ?r9}l+0KNJ$u$-p!k4In7K z4m5%d!`u-2?IzeE>RiB$p}&_BOh7t3F48&O;huI(!Vx&VJ$5CmB%KjrZev0HFLsS|mquXV16LwF!GOBd|xuq@Cp3;|C!u(V|`8FuaAsI3Q|_Of{3 zu7}3_AA}krbhws_WT_fM2Qzl>#)!8;J#0OCz?y9*jRc6uZWo6vlxx8TvAwY9dNk?= zFJ6%^JBIyUyoxa;|0?!t45v*0BTXm07R_&|?hQ{;aj_*+DR}TX-DUJUf>o4`6utu;*)69mrf*H^6 zV0mlmdD~!mTQ8AoNun_p&AW__zI*Plrs^$lLr=p}NQ;%PW54^HSs2 zn*D7Yb9V~Oj?iNmI?DPwWq0qwmQuOGlD%!mG@$L&1vH_iZDA(z0=^{SU|W09Sbgen zf%>z<4TIvM%R}$~R>GVJ7JGa9^`*-jIfaTjleNAu`>T|m0Nj`|>2KDxxO${sYfayE zitl>5VWc;@Ns{>wJ+5@a2Am}7|861Q^*G*3cbPw%@@pBJg6Qa)3;LW-*iFcIi7z_! z5fgjsPW^O?F&Q}6wqNbe(>?sL>!rCpv@Poomif%B(+uGiX(oP$37=dRK+t z6}!b3u@p=dY_sUu8{gw~^QnTTK|+fhBO2-7>%JJ0c)Lf+Pl96!r5H*{SXbT;cxm6^ zddl|m?`h`$eJAkxEfOSPW=sY`v>(_#f=dPGro8lMU&uWc2J=ItV*fL0w7)XgsK;LQ zNhmWrlv?+zRPVX}?tA_E_e~sw)W`%>|GChqK^X)274bHFW>^qP-o2|Y^Ys!1n5>C^ z=qCex1TsvNe>mb9#WORM$}LY(RT~Kru^y(#-RpPy?@9o##Y04UtNK|%izXexP~6J^ z7R*b$Eo5SO5S{417b<~2RJtm}OABr}lup_maMQKWjJl9074u&;0F}WI9P?PzT9_`D z_t#iO2qghRo8jN(0~Y1JJQB#T8m3!{3{e7;5$NpDDJJ`H}IvvH4D5mXWvG9#8+*qKPHX#uLRE~ z$dOaM_*7qC@9uLt?=}z+^-&wHd2>AUO`w|Vk2R)3?!xen5eQ>`3Qe=gS4bnK3mf`w zNO|Aa`F|#-Gh&6*(G#LXEf^Wy`)h!GXwDsoJ%tn+i4rUr z?3*b2hZ3I&M!;>geW$7XE=6k!bqFLAzXf~Th}Ng_wErQTFSsvOvlyswQ(blwf2-nJ9lc@e;TMrR_&i zF1YQ4L04ge<8mc*iN_N1UpK-}6J3>AP-$~`#*`saZFWVMM;AsSubsIs;>&JX{ypAD zdT6jL&~mMHF*pQ!AZV(d^#O-JZkuP^?rMJ=oAMhf_|@g5*+GXTJJF#09~whBAx}_* z{fB*bA+ z8!FO8NdxqXnXR#y6unI?PjsJ_RePuMhq5jpg5Mjq%o{ti5cM;ddirFSF)cX7w|HMo zVF;eH%cjt^*`&@&+#9pl@aA*fqx3=Xd|c0n*tE6Ng59X6S&daViSc=@C32A>0v8y_ zGTS{Oa>g3Pw6)vUliz2y_rMP`*hUieo2tzZ`TusnVSN9fHr2o8{M*J6RaIlEww#7a_ErRhqiTndK<^sD)&t78>IHGaE3Z>5;6|!FtF^u$n@h&Ue`L=nnnF<1VySC>LnFkpcvkeHKz@67IHAO6_U{bxJd}^)Wo6JWqxX98(4b_uL0goUMybw-m~^q; z7|(Ih25z%9X`BHs(SB0pgA{|i;#1C9M)oe^Ij^aMGgIs~VIyK#e-r*yyqSh_*>@^B zF_y_zzFfpT2Tk%;4>>(a~jZ8_$ayX!s%$i6oTh< zvDX@JEuvx2;<@rBS3(sg9ZD{{(0c0JWY;i)4%r;TmVlcmVtLzhaNu*imtC)4eGj7? z>m0dD?Cmxy1ECBsd`7Hr8$*_ok$z4z9q0#WtzASK=HZN)OuK94>x4loNJaXu+u6fw zQAbCNEF10iU$Zy6k%ba>UImxyVrJ%^NVe5B^m0?Q>pzOhO$*1Ukd1H_Pj%V!k52%8^+&ny58pIRiLDXnv!8uCY%|nb+nh zd0g)nD)FYJx4Y`j;$(0H&P_+3-#Z-am*@G|1LI3=O(U zv5J=&TRt*T$yKv+nXe`(UmGbbeqy_3*Fl_+TQhbl-=EH&@;hIB&VGg1)Z=A&Z?x@uGHcHifm^+A^Qnax6vFz;lXPIg-IRWK>-t7B2y%jl;Wh&+1^Srh33E8#&qogXwMMEp^$>Qk6*OcCt zTGom9=}%vacxS(Pt)=1Qm#DFDan?UtJv~94N9HEd*1+EI%y+!8&f9>$etF?wPU=aW z+Z`rDUhC+CNv|C_**L-MpH>>mM%smlwFacU7vE4iz#)#1{g&3%Ew}js-#4GgyBI`? zC2t)JKUp*Z&|2-(Qw;sp@YL>8FZo!o-cGqInu28@=RP@IQa?0zjp9TX1|^&}tH zjvb{sU(>vcd3Sd=@0zl>iNWw|EU=!l6cwq^-ZE)Ad;3PGmCW-e-BE<9YowfBxh3-+ z-LdUXmE?!|r%gE}FdD1TJ9aX>5er^lFwfvOUCd>NfgzbZEwwuCD0YJfN7H$`6=%f7 z0&VFVNp~2_Wb$Leck70AV7jNsb?w)JSM{@J9a9hAwl?Lrx98a&`JL-CaLg56+bP0G z24ciM;n)-%n%))mI8ljZ2rC|F@LXx*y0%Je@whO6`DN0H+4RRhOJT-k*`Kyw>`z)` zR|&4s-;{p8&)NE*@1_|#=32^;&S$pGYQ0^m_#U5C>!FArJ*f)4hHZD5_HL%?WTcvd z?Oj%QGdDX2inCd?4XH{2=bP;X!p57`MxC1Zh6|ax7u$KWh+SNf!6toab%8j>NJiaH z$7(mYj<_-Q9F2$iJVlflY`u1QXUKo$EdJx*wtZ#A5Ax}e+;;&`6S$1*n!n1r{2VXd^Ukf)eIyH7dJg9pYP!D|i9 zT~$Sq-(t^?Ce+QZ(nrc;2#iJcFXY=Y+ZOhWCcxK$j2s{5;V4%1NQtX6hV?4Mo9*m+ zNg5JA3NP=!ACz$vM#9v<$80FXYwUV+p60` znEqV@<|oQ6-#EdBJNxUl8b0F%a@6KRpYInihF;$zW<@{Ir?SkxEE76&s!Ef@fx*OGj@7}15UQu_9$_&r_od@)Ua*s z1A_gV)mel7eC$}BG2hw)BsXbqptlYuQz-3k)%P3GrnKq=u1TrG#y{1 zoS&*JLQc5TokkslYHOh!^AEA;*7UtV>@j&hk~4v(SV)l<%u z#EC`I`CzuaAIQd1!(Ksr*07$pO^Lhs?%l8t?Afy+$}R#lL+8nZ)W^mF^kFz}g|A8J z;Y&R8mAJ^b;ClhKz=hn0Y4}ehMPGkS*#aV0q4^-Fj8w&Epo=^%Rfy7)O&cUDn?^ z?gvc}sI+mG5K;D%c43I8z?R!(D%)WkADP&0=wX%1tpVzVIsEHh6BfJtB$E!muZbc& zWVDk$smV4~DR6pWm}Iv2{o2Z8kIy1#N5FewPsw4ex$Is}J*7TdZ-V0&>%Xgx00M+< zhvt^{?xT)kqy?1Ms&w&ri!K$-RQ_1Zna&onQ^KbOst%(r;#CWHh}4@_`mmQWnBH3Z z#u0)}KT_XZ@3lV`J7)Qjo0Kq>E^ZsRBBD{aQ}@P#+ptHhXM= zkC+O_lcvxu-IiQiv|(wafm0k*6OZu{rLY?7B_Vv23qKH)MG{=L7Q1Dvj@@^qgLC6= z6o@u}JGlEYQ78qlz8Q;l&R{l>bnIdUCmgK3c@AqHi*g{{o~g-!<`sztS0Wefl|bEs zY8g@5j@^iZ8}RXw%Pc9~^gj2^xt-7|11CkV&-)E&%|XZ4R7WO%l`0S_aJu7Y;k0Fw z-q~p;zkRS}YOC2Z5(?`qFKZGCX=*MBtB`L*h?U-``nUZPdM@uPVC!Gvb%-Ngk=f{$ z=+glQjUhA1pxqIYoe?A|d0ymtF@O^BwGz;lDYiTAtE$LD-nT)7>v(z!W$51NYQbIv zmtQ%dC4}JJdVQ;6k$biW8T@xQF-0UbAweXCF9a5;Dy{WxlU!SAAyE`)JA$w5q$2l> z2qqEP;m?!4q+qF2-Q7XFrt`}o-wHF@FW91La=$Lnh|NNuYNqTJ*4`teh>zK2?g9CdOm zim*xUJU$ep1;>9vge6P2O`_j876qqFzfmAlN5zpcJ(ZJ};P+;C8C=IYi7sU+0ixH* zYzY6X^C+@JMa^*z3;D)p-6BVKt#E<~^9hw1zsuOJ^0r^g8j#kE;QKr4Fa@1-nl*Lp z7Ry?j&t0qTnQ^m5&_FP&Sm3qr?&Xid&2)L8Un-^u~<4(FHjUPwS@7D2brs6c2KRtZ>3P>f0?}#XFmTd*HNw-vz zI$p@H4YSfVPpM<6Smtc-4$i9ILIEe>wz`J8NHa4Z*vxDKX5!@`MK5#Z{-eKh#RG~r z=7J3ZH=LAz84fB9LjQ>rs8jUuz=c|@Mo@C3@RZt4h;9{h9?Fis0s-a8MS59po=ZWw*(j>ZUgoZl(eWj1~fj#=WMG;LhDkse;8 zVX3F65-`xmM?3`sn-{ zF5)%CCn9lzQI8Tvnsg@U3`p}Fe}$5oxz-K;RYq}yyd}7;`gTi1&c0HFS(mBk2$XbX zFWb8pl6ddOz+a-iwRB)}EYXq>-&#LS zC*Na!`-ySf57~sgJ$p)LRl?2X;n^bTM08QR0z~A^#t4!yqT%dQxbmAxu_F|}%bh%@ z+RFOn0Qwf!nHJTsp}pJ{vpEXt;p=MI6!?Qz-zRm8 z^wAW3-z(a2G%~}LUqWm)^As`&fa>0g{>4q}krEy%(GG0gA_Le2ulRPi5>+@p1cZNC z$>&%b*(?T-ErYZ5DGB+}y_Wu|M5r_*#CQDDOWFPlZJkh3+9GJFbuZ-Ulha;9^<-r_ zFAyb7v)G#W*asD4*#s`gcOQh>)Q%wQrYeJmDMy8$$b!nH`kYlPpY4--QSFn{N38a* zUGgY74Fr6YHG~z87Sn7FVjne-1G)1kgQZq8Aa7agGays=M%sy^w3MFJS3GT>5Kb(f zV})UAbJGd2!YAhCD#)$e9r&v#t|iweq<;E$0`>@Wa+e>$$_o+kn&)`pv*wpQA{0b~ z%yV8}#2omk1p65ggXFc_{8s-4if(+Gn@s*z%0i(o*gbBy!Eq&kylQeghj0wr_zWnp ze^C1;Wf_Y_^ob?#M^<0FL_3;D=KdS?M^^wn-hl0H)CqEtPu_Xg@|xuoT~Hx;htMBI zq>oxx0k(ponOcm4A{>klU|0@dcr4#e80_nW_S26_9Hm`@+sXf6y-;H0hV7qL225I6 z-tP7=sYKq3J|aP61(?LDbQqDWIUJJ}?l|JQRvBf7`vQ=O&L|2g2Zh=Sj{wJDdY4;W z`yl1lNDq<8Ti6VFi}~9V=p``M_OR|;1u_mNTs-mK#lKHmAoT)gy;_n*1v+rAR_}Bm=yb7eRzTRk2jQmHhXGCl029*P`>4!DQlH3|=`tAPcJ z+rx?f`1gl6B(N~+X$*~2m2F2ppk(s@C`p6?C`n_p@IPisMMCkFA+)&NQ2$AEdAcG&lvHkmK{xA@f6}bC#jIadl4@vHe`hymcLRbU-F!mR5=qKpu z@$s=VibvlR>wLH8t@l991Dt;K0{m4!-rn?g27|D?R}XWbZa5Fi|6G%5{0~qb-KYxT zf7cRN*AIb6C~Y|IU*!I?#G)VzT2Y97-9uxaKcp5#L&o%`fF~#XDc*BHXd9u<^WQ%G zmn1lVoAJXqS^iKkIRcn%#`Ep*?+Ec14@v>7h6~hG;}1uDOa{zWeT=>>@rP*qz=qiN z?=AU53!`ViY!=)2Q^9|T_6F|*bQ(EI`;RRJwYgpUDcX`hy?prMm~%b;O>k4q28@Q^xwSs|I}jmgACCGE&hn3$p4Rf+mam24*}!Y zUpVW(z@_Y7Tr@-@{;y2y=&Y}Xq7!Of zEiJBJ{_5`o!aL{8k;?8{r#j$;IMBiuTRb@SFE0gg;_v-t??W2EIg(*?qd8KM4M^Xd zRPlh}ZhDIAYZlT>WGV^%aZ)@-3}_f7%kzm4EPpm0l-t3w+PzINKa_xfO()vTfG1#4 z6N2qudddqpev}(B%kQve{1F>Tr0q251?x11P@OyZ96=%s9u(jLgf`tuGFFN*Dbd8e`tnfGb z6bpvsP`}HKm@ny^`bB;Qs!l(?yl$NSoW&E8m6hdfP@Nb+r1N?|Q;2}uN{vaQ#r@TM z?CI}l@Yo;F1{qKLEj#EL8vbh8=9SY>oA*dND}MJJo8=4!XdkT)2gAn0*4u&3W_Hkha|_EGj}=mWOY60Nou zp=U+v#j@Ys56srW)>P^ZeAcdyRu4>5c-$hr6X}cTWTHh+cIRnJb?ReQnN$j9zqh+7 zetv(DV542#Pl8P*_a&LL>+G=^z-;{$NvSS@5Q;0}L#m-G4xyBR@z{;24P^?ktPf=- zd{#&sSP*Jv6GrelcprVn_Bc4qYwv`O+1ftC1wjLEvXfPY4@whs# zt=S$CyTa+nV%2tH(k)9T7jzI!Sgdd~HNRSHG7qm>&@9wZcfe&uePZ#2?sR`K=_lzE znW+-(t}TQ~>pxMPsuOU=C%**|o5^C$s-^tn zft*ZUM*=>-z4Y$)_f#Kn+vR|-GX&~Uu)rVHSu_j0XZNi&%431tT{dqZ!F+y}+i7cp zNjBy(x97Se@Ivmg-fm8V;?=uwTvv317WeFz!o86cb8qeh-}`;8Rw(#`vS_=;0avp{ zzwDNceT0ltd|{a)64!9BT=af-dHaqee!jLWR4n@1dm zZSe&3aysXf!LJ+*8GfBGklRs3Y)%c`3xrVGC?L4o7hCEqYfy;DN1GWZIan78+SF-k ztrg47Ia?YJ3zqM=#aDd-M8)O)Osj5@Mlk~h0Yf|)kDW};TMYWwRc1@ZFDkKr1)^*q z(~{oUZ@D^E$(eHSbWhU5b}JpCV(5>#=_43 z2yN75D3h;r?;(eQccE5c>{@gw({ogo-$xgW7zkPQ6`XMpU@5TQ_UHVYH$c%LQBOT& zW_4v`6To`ZqL6(|HiQ54A$8z6NW-iH3@$>eJ!NzXY!o(B;m!y?2_Qs~%C-C_?Mrdv)H5*FTZY6pu8%sA(q?o;LW+^!` z_y|t>s<(RPce+3=0o8`!8so}eQTkm{qv1YOv#)fE7ry$b%B0s&LByt`rhUS6DDmm0 zQ=*Uvv6M|RgZj%d$m4hp&tVeZMf|Sye6Pg z%n>0H-qju};#258r=h$QE-1~V7sh&ly>>Rp^QnxIyM>xntlE0%gyygxshY7(RZ1A_yV&Mqe)QvO0DqQ!jpMywp7FAAYVXA@V$rg);ouGd0Us#BY| z;By{y-<$Z~GvxYKBVS+NC)QJ}d`_z&)Y!vmJmqS|8VZf04FJ@D{C4R@G?iF%(>DS{ zLjll13v6ei6t35?19wJ6+~G!i-iQjim+4xbCp(3D9??`!q9_CyQl6N{mg?3Q9f4ZC zP7^uW5aK@9yY-6$i+(qyu1}+(sMG8QEm~nD9A($f>=y)6I8EQR_+II3O_df8SbwX? z=CYmTlF4vvSIvJ}=y`d*U2e4mO3LASJ=O=DY3h&0Kq#068R&1xq<~pd?vg!wQD?tc zMl74aqM4X25iD1tRXMS~zt9>7lu$Yp@18flntO{u2x{2)aE&-c9GI%_kLF6VkUUak z!1QK0*V5K3*U@&dI?ZgQvrVmuW%oJ9+s&%A))*YgmRKFhl4j$m9&zqEG?$m3w3_^A z-;V4V<|wd#>~|egq|VY`v-vdd&E^xkq`>#~3oS91XHJ8#4vCMBaUTrLO5uRB%0=zz zn-3=L#xmII=%1Qd{Ik_Y9DK|jK9>l`&BgY1o0%#p;j>jjdN|-4xvn6*Gc+1XtU%kj zIt+1NR7N;1IWN`MRBlzQ5Wr@AfTt$Fq=f-A>iQaQ4(~9Wm`%k6N`u~vgLk<*TdTTH zC`u}$-}EMCd%Aou1fOw-T9xVV$wZWyHOrO>#ybL02hN-=&A&Ds zv#&X8!WLT`C4eo;5yzmIaJa^zwI>TvgzS$Yt@ixA3*Hd|yZr#f5&{FxNZq~gMSWSk zG@XD~QodU7d3;30d48=ic{L-Py298v7^>guSxYeFz&GZKJ6rQQSMQzY@s@cdY=xh# zBM)7}Zi0^&5;c#cwFfkTzV64(jzWnLf<#q=@aARu!k^yxh71)4W0-g7wA;<|H@fbo z#apj? z+r?cyT7n+T$}ruS;4JMc&sy`7bPtu9SDZ=bbgWq3w8La00sCVWOaExN6z$IjDVG|C zko9UB`j{6$dyTb1WHoa)ky?uZR)Y;V1JsGV(cftGFL~zD@3c*qXsc>B*`C30NuNkQ z6!N44b_X`lUcjYUs3O&Nc_=S`WrS~fCVZqTao-i9q*+`2&(c9Zop zzMs&1s^mr^1aU-(cCA)v5>sb8$NV&3G0yr%FOI8lTqeq(HBYbc&}nm7s!;#p2NA|{=Z zeF?PresaYu zA?ytEJk-BKgt*y{2*#x>xWj=rjJMI~ydI+{e5F>}_w2ew3>Al*>T6nkG>ud^2KYxJ zTbkL`c^19;*2Lj(t@RU+L&-+ZwXhe-yxOr0@}F=@ML%@ri#W!1kF|9rS=9=AEQ4jE zA7``bw5TPNVt9xA#Gz=9=XG2jC`lQg%#JFZbCUz$fk5vY`^C0Aach@XiyFX$tUcjL z(LjQ$1vIn-<9-wm3RB6m;^uQXeETKksjmKXjkdE3HuxF{Z}CyyUv+Bf2Q9THwC_mo zeu4KhGVl9e`>c(01js4BPp zhuY1qt!CFdPt}Klj@I)WS5U3+$19XgJ$}NoU!?MiRhfM)a#f19!SH6qOy#l8nbj-S zplI|ujr@`iSe|@B-gW(=Z*@9t_nb#9;v6q! zM5Dsr8e{4zmR_E@o|s%i$Q}LxIH|;a?hf*F*IGCRr{NMy;*ID8$lt{|2k1!0o`CYk zIcO?wyBD1+?7R@22zB;9B@c|z+I|-eDcjI@v_fCozyonGRVB5wG zs862BSyiln;zLrArIk>}-N)=D2f`9<8h+JlIn~}XDx?Banyx$FOS?J7`r{b$9CJC$ z&cY@Kq!kDeSj6m!!0B3K?Yh4}59A&(K+;wy^{#Za4~^2~GI++BZBFWVdrAZJ&=M<} z3Lf>4uY?#cwLP<$7(b+}0W-J7Mw6>N@kdSnu=XiHo0N0l?+NMXRyzKPPL2JXM24odb3y zajT~iO#n_w-yV4tHv0>P@0v=Qta32b$iR;kYSzLByk=OH;TIC`O_Thf{>WQ5j&KbD zvv3j%V`Kj+*m;#{FOJww`#~~ZXpnkXF!>Bi0nUcIuN*73@ zN*7+fe+C2kRFxxszDL<^;q8mK&<$2RX2#!;(!{Hg_r5-|e6sc9d7^1|c$p2xjd*3~K~F1b{`{5r>Ek^91BRPakKl8l7nYh7i5xgp_JuYs&!9NGLK{f{qF zs$ywI`n|k_5hz%z3D0b23%zBeFxNEM1t49~iER2RY*d~nTc)Zo(@OPh6Dd;oBo$T? zRQXNCY%mHX$Mvhl1NpVimCb~j7}E^%zj5Z|G*JiRC)wBzctpfzLKwn8b4kd;^2_8e zFoQSdR}8vuQzb+CA}It=9fTmR;;Z-HmUlaoB-%-Sf;7C{2M2$ zG1gq2uNJpsx#cxBXIq2m=|0gy7MomjH^1ijUib&8P8oyR*RYjX)B>dTKco4OG;9)$79_B|~G!@)bpz1!z3mB)|MBEvLW% zUZeLUX}^p6o^LYh!{AkgmuE*T9lHbJWmJjy2C9UWP0aY6DaJM9-xE5pK@Zqp=E?hg z&$g^m0KnaHu98x}u#M|wpk2RXKd_2lS`DksLZLT%bcfFg^}~H`IihgIMmC83U;t$U z*%umkhHbvfm1DF^N5EN?>#mh{lTDrzpVM<#?p-bTlGkFf+ai+8Ks<9c&RpklegqtkoGl3jn??ImNBB|>VLHlUitDx4RTKX=0ke(A z^7oZXN@|moJK7htfvO*sghNkB81YR*lHVQfUt>Ei$M7;W2M1%003qb{M)eF9Se`+t zRqGT4Jb?H(99I}eOfijLTccFlG6m@tRGXY1ZG0DUvS#V^H}oU^&Yu=i9yHi(cQW7X zmN5Km0kkdGDWC43bx(K+Z)@*u@0&H>%qC(El)ypY0V!*>R|;DDOAq7d<%t#5nZA5a z0xcF5@APySHW;-LY_aLo0Pu@^e{OJ;TJm#5fHm=}OJTojL6>NvUzGSi*IMn5)CNdZt#BWu_i838f_Z00Rx7ZgA~f_D6pf z;(kXn?QJMQf8y7)HK6>A1+YKaPhV0ph!IBfHL?;epOM-SIz$xYs0IzMLJ9Wkz{0K% zQn~Ct;4IOA@Nmdzx1wE$GJqUcZa0;iPWObI*$Izf+{1ajZ&$b8Y_N{PxYG*X!U9ht z{%?>D9a$Q5lZ!lQsC__f}tj8e!`(nKSFhj*mE}k~GVa3{9XX2f7Q~K4k#dLcF7C@4)q(EiOao-U_SMQ{FpYBqq90?%%*r z{K0NU;2o$)h)+whoPd(N<1oHu6abs|{>p8D&)=5;kRyAxL+(Xy1$b8wnyi3m@!5>- z4OhhgD|0#kO5$2l4E*>#k$a*)3&^mT>1`_m!gkW2dTQKif2Iwa#VsF-%Ocd{`I~5Z zivik0zl36sgGEq$k~f^j)nh@6Z}dAcf76g}%|SrBY{hrqsre%SU=vzIEBU*-8=(Av z$6Np?Ba;8=`)5HQk@v3T#eY3Ra$6`Gy#(;(A3I4QYQW=vAro^pzsWe!5JEs)$LM0SdWckv;t_M6~}cb4*T}$pBz@n-5`Ezge};d&roV4wD(i zRh)nG2_kK_Vv;pHg}dJy$0xA8uMZ;%w|fVEk0f~)7zjT%>+5&9G|=Mov?hjki&@9; zu;LXtz|W@4Q4=9P?LE|p{D;e*ja&ezULW;ehmACgnlp{J~@p z5#P>_@X4n(*uPP+WV(@N&8WxP_8R<`x6F*l)3sPBKSQS&r4>Fl1C_*L?ikJlB}?c{q`iCS}R$A4xu$Un)wBl0WtCA zc%4?zuU>#(%yjeB)zw;8Fz(iRfpTsqUzq>bKxn(~RTBW#Nc+IgkFEK*`FoS{!u<@Xp>*^Cl=?s)|M6` zRMu##sS+jt%naMm`u3~30ECgbb$+>1fMM1B8TCJOx5GE@3xxnEfZ&(?+#F|wN&x_{ zY9~-KWWPLmtO6788ApFZO)PXD8aZa@cSSGYx)U9Mf;G?)h?WObbWZC-6dp%EB5GcZ z(tt)yRR4`X0>D=KwrT7I@&kZPP{%EtDhIqvZ4aP9`hfa*EepUSlQ~W0fEJWnC^#|J z7UL3t{tKMS^crcjB=Z0gQTXQ4SvFI!aRALNGl|1cXP^&&db#YrYb~_N-fYVA(c>b1B)0@|WMc978Az3p~s;ha+8~WW`)ptiy=mMx>e%T~} zD|4OA3{Adbmc}xVI*?N2KF5~L;IHl4?~I|9j`#NkzE}aMD^vjWN|TLHQmDj0jXoE3 z?A%}zcx!!}F4JcLs<5PC;foi$k9THk<66~K#cX&;!8Au<`zB^@i|vx zBd8E{REG(45xNMv?j#>(2Nx4;MK)zCRv3vj$5d=+S6f6B-9b<kYgqY0mAsF@CfnK{Ok`7?azJ+uc}~X) zqN?IP&4hv|(ag*Bn?FfDW4)HCx0{c}AY{1x8_!L7o6#Eqq{Iz?4bwUQ_%hI0PS1L` z;+21pphk(-Kou@lTkRU9Irc+At*cUi++k*sd?NX@WI+b_f(?z`Lbbx!kBV6f45cVo z#05RFz&2$qd!jQBw3-gV-$L6xkBhvICpD4voQc`>ZkN2?p?AMx*=_H;_T&YC6;-|2 zR5|7wfOaAYJou~A@9)Nezq$ql@DNkVZyZQ*SmIf=RYJYKu9Kk|0TLEURwcqPt4w+@ zN%@>UR(+mx8uhroY}{FB)dlE>g6}$16UH<4b9JRvodPWIrJ(?dw?MJ`D2b4*gFx8g z%YAu|RH*%YlZ*cbr?9ZF6^U52Cx>>GB;cbZzQIA{d)yuLHH7Ss9XQ7bzIA-<2Rf1O zDt?uc*7ZhdV+4D5zQssLBP3={Wg*0o74iHja}|kl&y~X=L`T4zOi$qK?=JGcj=r}j zAfUCQ>j_TfU26dx)aKNZ+%eH~aX}ud37LC$ScKks0&YfcJ6p45-+)%qce2NA1VvhV zXF4c_7NZB#08wLeVlMGn4v{CJ2os|NC9#IxGq}$*!R31JUD6!Z33w&&7@BDevZ1dQ z3?Q!xTuF^u-H22OXdX^$NfSFs!vqG$GoihaU{|UNbct3HHXS-G=r?D!DsJJ5>ds%- zC2;bW5%_oDDdR4w?7k*}0UaLHdydhB#Fh;o!6fSR4KK00`-qnbgC$qGLumo1yuvIv z9191kL#Z|?+)b_2unQ(eINXEiVqMP0F(?$V2WMRXO>6qZh!a+Xj>j!iG38>3(#B1) z1G?pWn78f{KTF+KGIG5y`K`yntRol;mzcYQqRQo6K7ihPcJw}^p$O+@RVuk)ZV+By z|2IW}u_H?!2UbwG4lNqTXb~6g#$H@rca@5C~tJ0P~M}uoDHgBfbE&|FV}0V;&=9!fNI@` zxv|YgJr$(D@ZQa{K{$0t$qICnn=DfOOErpuG{8pv!NlWwO+v_w-+`}}VC#Amal9ynulg5db~aD#*8Dp7w!Zwql9!gz7D}Q)O$R(vvefvdP*kbE`i_bg`w8r zoShmpPPoJzaKD??I7PLBm%GtyhfoDHEPRImvU}cZj@Z6By&brb`M|R{7yhI}R3A$J z8*664@2B$0rm{eb>Lx7cUE+$c>%PyVcqF&mXZj~4B}tx~Bm&2C zXnnnA-{Qz;3f^E(uz)?#4`zgfOuMd>`=+q@YYxg{82Q5&e@^w@-ceGoiz% z@6qbSE0LU~ODK$9-8QB9zXU!1k_~il3WyEbf%||is6hb{kwB|%liM8$b^g`$hBJxj zfP=06y#;7R0GjDW1cD!A%O7(Me?nR8?Ug?J1eIFry3tpE9`PV=U6?v^8a7AZf$`Lsu1l7!{_F*GjBv&A5rT0ng*1KZ>f-5oeS`r)D({Zp5)Q1K;R2r&O=w% zwzsYEZ~1t+pEwV=WQKjj1OWCTfwMm(7Pi^*=p?a_PY4E)Etj2fWSxn zLUfqi>Mi@^xZpWVcXXvoc38>80I+*C{>YJoQ$Aa|#C-N=LExPh^dBs7@}N8gnh{9- z!Es_49k=Sf5EC8l>d!!Rz;OwFa0GZ`a)N&*-vqjTQ7{%8q6W52DsqcD8kvARAHLk< z0=j@HtiAwEt410i&mT&+UO0&!?afO%L3(Q~C=vLlVEXshNb5>&1)M++s=qeIMv6ql zNSAapG2ZFFhp=!N>KeJwwyYi2(X)ID$%YGE^ z3B$234N98&G3d6x&>t^Lm(un znHhgVA@D$l9g7xHA@h$-y519evv@uiOeg-5#kj_z5$o=_g2{h6ZRiIy5ERQUc%MyV z+%}x`$1)@Uh#JZUk04PEZ(f<}MqR1y+Sjycm6fAZ=7r7n>GI;LpMo#oO6Tjd+(3_K z7^_}`s7}3I?!e0w=7i$Om1AI0AJY7_s0k6t5|&@nsTH$?2(zdS<^M1C-a4wvc5VBW zk`yE)B&8dq8r1^A z=pCW}QntiFP`=FG)=Oe1VAE!IeRs7>+TRXCj`%KeGr<6Fs3sIW;%hB-jjEt95}Qp5tyOKBz-R*Sl>!)C6E+ zTQ~{geBbVoaNmZ9J?&1_3n${RM6%y%K?5j>`kv>8m^+$wS(Kz*3?Y+R0lIPK-QZl! zg>J`r*khN?fMBdbD{2Wh8W6ZAnyF_fuJBppJT25zszCrt0w-0EhVuJqlDQ1ygdFA+ zz$1DvWz^`y(Rg}Pd~}@KL&9K{WF5z3_oypbveAjMr5H>KF|~`S-%Wlyl+);gitS7- zMiw(dg_winWb|uP%L#87+*CL46 zPj0YkC4i8<7}NcGLYLCola{HPEi=GkK|by8mm2U`49V=p_&qQ`-nSVla3EBCLmvi^ zQUh^50E*Bez&=o84{JO}Hy!jn+AUN`;{j-?62~{E`It1(56a)2e~!?i5}v$!Y@`gS zKTH(uPoJt|(BCz;w4xvsf8;1&*GEz7xmgAXrm4k1xqj#qunqdhFkCE(-pE(dI%T?< zIQVA$sY&S#$IO{N>zj>eqKU8KHFMQ+0X#YJ5kM4Ombb1;-a-CW53XCQHk{|~Bw%2} zR+38fdqDh^_{w%9Cybz9A3!FF?0QuS9E{wJ-bX+4i%z!YI#{I97xliBu1~mX&`#+? zv%S9TnRX}LFN>&iT~EmCeZw~Ebu_}FS8bW=b!f`Ouzc_Qv2>&MLX#ok&JF-%a;*^{ z#gOc1bW-U=!BqI3WLdoA**F)d+-n7#bWnd)1boJW+Gy0X==F&OpdV{~QqePohGoz| zM#}E%kokdPNgWsP^R~YTn3eA?FZ+qqeX0A?_vElwqXC3 z3&y93auY%$hMP}c&uF&X2Hb`6b^r5~QRTgNEz&=r{wVLy4`y;a`yX{vJ_BsC<8eh*G)dH&-NTLLR8PjI7RGxD~RE*O3uZcH9kGx%WKxXNGOkri5_|oI_twCzs+oFkwsNBe%@$(pK-LGv z-Ny%;ragH&J&m!0{TCC05c9>E5%GKI80)lc;e|^m zs6K1s4mpmAtle3X&vp+iZ~3KR0L}{g#o)}#xU1L53wfv}8@T|9nl_`Uev{aSoPy3kgvopr(1 zL_AR{ZhsE==1gP!3crL79wEja0PFxNt(I-MxAyJ+-j$yd<&7da53-)JAaIl;oFvAY zSz||6de}$nY4&oXMl5?{o03iQLap4Q9K|$!MzvHLK!80UrqzubE7QxSvbAUO*!mIt z37uV8ok~($6i3Xwcxko0p8oo$ixa-EFxH8g{oC|(Y>sY)NjLN0ds8;kdWBe?U;_B7 zcxYcd&jTgJ1m=qOsjV9KN!2g`%^*F~g0 zx7q;tMAs4@$v=b7f@eW4jL$Z*oQU<|=j}ReUy#Y!lS=xOJXOfJlO-EbMl3k)0wntg znFuOF?ed3(#46)aO&i=R7_RBp$bB?L>k0_d`TNr)lQUaG?nCQ%VXv7cFONQQK6Y^M z&9`Fu#3&ipS+B!j{Xwg0`xL^X(txgVj0VX> z=>(XIEXfocGcW8KV?XV!D0dUFP=ICkDWnYqTW&8d=J*2vN8DhIQ->)L(~8h)3eneq zvC;{k3h-QtrgU7~WvQME+jUqPnxTbN^whfVFoxaaFLK@-ysuXjNC@ZldHN+maeIl& zxRwZ+%7lVbQlBWz2#{-{uC@j^Op;{=R`~tEML+3t-J;a$t8KUU(i8HpMUKjeoa;$V zzWcj{`d4l#sh_xQX*JyXzBSo&7d`1{q;MEiK&rx zthv5Uvvio!?2|>feBhn3nkum-NRW5~3&OZ}nsUbT6q|o%qahPkvhGqo@*22(jCTqfq2yy4B z&URv|HV5wMy`<2C?cuO50!t1|>>{kQwEIj^v>wnNc|%#7-GFhaFC+0;uYnSfKanxK zP`TlI$=(Pqj3MFi0XLeGsjuQww5Z0=WD-o2e`u&YDnBVz0G#YH4DMj`Lp_4tJJxAi%*R9v4Z*%ev)r zGJg9T#HJXe)H)*1S8`UIHa85bjahUuvvSnZ^lNQRZu>#;h~OKMUW=IJsJn=yF*d8<8539>`V`vJXaS6mpjJw;Q|jj(1nfKNnS_QMVj*R9hu7h}%xOv0{;ytP8OP)e>aT8DE*S z7%O>{dvaLXdh#9Y1!fhz_6yq#rV4ik0s!sFoN3De12_OJ`B-@}q6T~d$0TB{Ic)Mq z_c;fg;qsvLVf`}>mv>`FF&v9llXE~xx8&>x_7D#_<33k;Xm+nqP-GkCLz}84T-tY; zUNtZpDQOV4aX?P&w?;}p0=1bKah;gSZ46Y8c(-3O)gu-$B5$+LMVpZV8A!A-B0VDD zesi((Tn5=-Q?*Qp%qIo_2^X<0`3Rew-+XJ=+dgB26*Q0LB7{H@3jHJ<1`cs6SFad@us&$xG_GfW4pBi#b zYhb~aVkX4sLG}ejmz8Vau=&SiIF~qf9Uge~8kT8E*;F46^7-m5iTAcsH$!h2RRR{U zE3U1&eajM2Q&(=%pC@P8X#LbA>F|R~ufa00-eXU*Jv!yO?QzC6P;%tv@_)w;`kGWE=u6|04QEj~9HZ2Gf<;mpNaTB<$Pv zK)&n$))lu+97xu;c=J>fcS!mWHYo(U!((%#;#$;-NWbadMqDJ;t(EEBz+lY`LvfX9 zMt0A&7=AWXsY5O9een?Kf!PF+soI(cHBoP^3j&~&zR=(!B=RP|rb&CGqW`9v88;%Y zw!KWhr{I#r#;6K(RBB_r4)idfxHHbRN5}G-sVO6%+q-Q_fP0k;qZIvcM@AP1JWv@X z#AL=5&0ZQ9E7b>UWElSniOfD)eF}(izz1EGF_2RZ{t6S+xqx zQ3;ZOW_Z0B^Wr)7Eej`r%*(?cvB^Zz0=b6&Zt{u+ItQHU-Gx^AM!+L{;EPrVQd}2zumOtrf33RT+fO#NS~P%NM4xLhMp83@a-F6FtS5<$>+}dO z2C%%OGC_!NM8^4IZ+ge;feSXvv`5B>eJ2~^mxA;C4z>>l*zTNhb`Ujrzeg88JUL+w zCM6|eC;N5L2#tv(^8aj&>HlZ}?0?6_jaNaB;c$4ihOe*hA+XCH2?PE^`~Y*S9&y^R ze69<-kThj4#$4;)odyUo6ST(vvA$mFL+gHcbfk|80j^jA#5O(TlySY^3ULbFtxrL8 zbqqw-;ZJQ~mN?SUBL1y{=Ro{rRupABzAiveWSW|9|EGqfg9O2?0CJ;i>%H z<6x1Nq(C73s)eOc$=_Y{r3&z2Rh*PU_HTj99#kOyt6UGoyUE8q^0vl_PCd{$zYlSm z{+@mG*UvEA^pl5VnNFfuKD_u1Cm@Opf#9IH7O-g%bCo|3vGxA>3Uc^W2iijVyz<9Q z4Zi&<0$@^iPG|q~uaNWk>3^_h5%=6r0Qmh)t*qm=R0(f=xk%DmLNpDaPIU$Cbz%C( z#~9&1l_Z6xdc=jSkkd)sy`IcrFs7M}ib4T z+AV&0O~9l^VF9F_JM=Q2p0Be4??ar3%Zfq*^SvAZxDOTHXX*ketnSwxfTuXlcj6c7 zRpvcDcy{Nn2Q!FC3Sx5Z98j`J2g1xAFu>Fz(xxlSz??JG;OQ!jdRC%WIS)>5V5uN^ zFb({>4B)eXylWzUN=jpQdbBs{iOpl$opa{1^+Q%MMW9p$INSW1fH(0i5FzEC^{21z zHdF}R88RsnNsA@Wn2)9Wr_wx$g*nY241Vw@TM_06q zwK*(CixQ9Os!dNop^@kLny$ZJG(KI3^V;~m?qsg=$!9)?3nVVyph1Eu95&1IxCJ$g zS`t!aJEdPcVvO|8`}jE`Q}^0xBUzyy`sA`Y4=e#XzKy^)k6>ctqA6G^0HYxF4rr+> zJD?(t9VD@0W+=FR-i+OHw$PId{4RHax23dof3)D9G!_Xbd*kVTilrnmw(dz2B{L{Q z05+Vu3;4e8G<01QufWtoREpLJxDk%dYUL>6WwMZBFb5z9 z=w3m>*YMcX%yrGd&P={ebDbdWWU21cv0V#e%2TuF&jmMA=fdcDT{pZp(!QBN4mYNB z2{__>b{16u|Ahk_O6>@5p>%+P!z2bI7s{pkP71Tixf@7h1La1NiBwv^>c9Y(Jl&0t z+fEgBDry`pdVmc82=}t{i4Qgr4s-3V>EL6iMvGXVqo7P968I-zw2IO36^~zo9-$uN zF@oe^EZYHr)r*I@kE1~K8<_`luT0G^p!^=5B@&M6u^7twb)P>GX=uCx7h&92gof{uMb6srDOQU8cz|j(}*U#rKGI zlAx6M^~*Xvth1O~(y$h6u7X4dF>&$18iywgKR=*K+M*h5|G=XZdCDJ99tuVTQWF5= zV&81Qw6U%$EZ*oexcWMS#!jT>4PrNsC)IQe_)OZ*d5TKG1TVt?!cL!I-_06O_- zsjMR&e*q(im+lAa*KrT^wudxf3_rMftd!^t9ak8rA7xFwzu6DU2Dj2U-46ksQ^EL6 z2^S)>t||=Yad<$*ts)FhViD2DfFv*xx-fVvB(11i-2PA;2)O+KEkO=6JWVIGr+0bK zX3~3NJO1noH7H0}5V?i|GzF{TWd&5j?P=4WDq-5n2_74hwXEk49Txyq7YQt}Z3HJz zI-(z+z_)6E`E2EDdAW9V?5NFClT`qOjfV4rrX$iC8Us$?Q^NZ~u8}7&_h5;D{Yxik zS7GpWE*wKN)=BS(2eRLG!%I;#P9R;_Nv^bojzt7;cw+^EdLU2xeIV3uB5~A@q>u3i z*x`x)J(t1EaX^gNO#->Vk%Eij>*d-<94>8`r0cnn&^qv5j=g_|*bg-o93e*8XWTb) zDdDH6P@_^`H?mg5fTP2FPrc2 za&r&VcD5Bp4br6D#QmqK09Y?jZt#bH0*ChO>@1SHy87OIftPRJ(o{m_Wo22K4-O7o zNfYK%JI!Od3VC1t%|_TuBChzp^Q4_hh3ub|2mW!D;4Rb&b;dmA=D(c9H9|<)4GH*O zB-BzR5`W)`6F&Hj5$gZ^=sS4*sKng--o4|Nk&`P@Y@bAI%a>m?x%e?RbnENuV)(_|G7Zh0KCrrf z0Dmp(@@qPIT%ZY2z;9mj<&b&=@gf77r&(WvocBeZ|Le0O z{O0G4Y8}x4|7%|!VljCWG09nP2iV=|U+#OCPv_45&(jtPxZ>RTG!&zBJyXK5yC{uUKmy6)__qC z;_KrGaCF+ zNubT#C?gz;{XOlP6cNu#ExKiw5QD?ya{%?QzOY_HNx@^(befwFee^#b3JJL~{&DrJP+Pu`<_-k~|@wxRM8D`S` zcaNA}_uA#GDYH*|7yajR)$Sq&j{t|rOWrw%I8Zf$hhk7WJrHqE1j;lbB3EN$@44;I zgqw$nM<0VztA-d!kAkbML<4D|E36 z7~C#0Xys!E50%IZ3lh@$8u8L9AwvImO!$%0qW44JaneI+kO|tDqVc0bgIN#I}O zWxU^6$ePViXU5t5%m8UN0J`5930AScLQPFae4jH5YW3L&F=I0CIbEIuWJ@?+=KD|C`VJ^=pHB#zTBJE z7>&!JGkBQIRTlRhR>yjEUBF2|Sfo|@#`sjlsEna!uj|}yx=L}~=;I^ty-jeG%}c7Q_tR5$q$$!cfc>6)VpUF*fes!CCHF*wt%1q$3D|dGzGpw>M@na|K=j_f zTK$>A&jteQ4C98crG^pt>aBw%?$`|T%{paLPbD)lsLQUR&(&?_J<)Bl2m2xYr&Hey ziKwZ%=b2BI`V>Vt2brMJ^iVl)fVMwpL^Gm0)At+6!ijp*dJ(BN*&^#>oJ|T>4i@gD zbf(kEmmEztIH7|c9MZKq-E#xYD6su~x%Kbm#i!crMj;?TE@JiuB*?(q$I=wzjYhIF z$_dQ=hdYb2lZTbe$3K({PLEcBl!yA>v?rwdK~aH|_0)SbkRsfv)p>L~!>NB`YP`~u zWMjH6^haBG_By$p@o@XK0=-J&_wb{;(*hvbx*2toza1o84oABd;9$Z8vZbF`%t)aD ziN$clIHV)k?t3UaxDmDgteKkIn1;u!E9)s7m@4ni z_+%7y)|!S#=PbTLHPU?kBX3#E4R$5IF+J$x%tinp+*l4bN9+2XOeh6q%|M-4>8S2t z*&pBxEfb>GZVFiDpc-Wzqg=hF?UEE4t5*q;2lR-;_PpZSR3*8%=bpBO#J0V|`u7J_ zmQz=KZD-0>#&Rs~=cp#*GO4FZy(W3YEq_KiVk349)BG-2m6+{MNlXxAwSQTL*PB|y?-o*8H*v+aAUtmP2bO$p1H91xKo z_oNE5QZ53HX@$aOqG9V{#1AY;DggG$mWLK7`NMQH{ZF=+bOIV}R*82{s~TCQHG}1% zDEw`wrdvT>${w`8A!5~4IOSkp!v{^&g8J+lf|*`YKN-%8s&StSv6LPy8r68Gaf{#8 z56nRT$wDf`!5q{CfkXQvBr#D$-2`0l3EUA@O?*;m)(4hA6b9sGiKeT}$eisM5V(#0hMv;`+-BYzr=yx}Q3z!=$;wQa^Q6f9* z>t*3qn~&C}s|hz7W(;#l!3m&4C)F(Yp#wzETVIiLh)vB$C@vGe=Y(LNVF=(lgfSu| zDJi0!kM*XoqDw+B&VZp7l*%yE?ezfno$CaSc)bQyTF0H6PkF2%UOokS#Yv-OF(eXVc6$6*#d)HDdQZTW^1(FT4vT zs@ypeO0U&iM{l#bir!=>>g44o^M7Xny#k6B@f7{q`CfL?F*A3v!|&a@r?d-rKvSyGi@&6^isR3dkPQb`-P9 zVb*!W8_)RY@|JaRuE{%Jm9$UW*MHikAmxhe;RDr#xok?LgQz6jFa3aA9v-LM{6SOi zSG47Gt>TOx%7eOl(v%CW`@(H3tJri4b+>*7gu=K;=1Yo~;p2pGkh>5lj+$UDANngd zt6Ou~OCln;%O5No2>d(0XyU*CKV_8z?f5K1$3u%88;kEoOcqv9U}jtU%1z8~+v6NZOu|tx#S~l#iJvj7 z)lZV8RMiaKRk{J*d)kgjJJR|7PCIM?!HxG&9{X(WU8vi(&=-y)*$6qXkyHH~G8@Ta z1_j19*9Ufdo>bLaA}cK2y}aX9vCn#9U^@)+OQ)`hCh!XTF6luUZq`rxt-=8#M{PYA zhm4o^O@Hhx0J<-pmKxHy9K+wiwx0p`RFtpy0bIiSc+%37JdKZvkr>^N$as&7D7oZHw8hq68n(Q)An*a!YGR;fkm%L4KZ*l9B_hKyawN7$BY-ZY2q@3l?CLs37f;~ zmgS}TkE1{kOwGTpBye%7)I56eybqEHM z5EB4IxCWX>31GT_49F-WwpSA*gz0o|m(a`71Nt$myU4$!x}}KOiYbvJrWeT6Y%qQr zgkJ{4-tt1qU`OKy=mm-nS99`6>hUet@rW+^m^MMt`z~=^(V^ddU7RH~SqFv9WuA4L zF3k)?*@#E!f$1}zjn3kc=II$)S`wcjAZhF-aR8dq^V)8kMz z8Ii;#?f0&G9fo}ObhTwDt^^jf7q(NM9)lKZ1=^+h@4LBwyah3kn`cKOav$(`#enW< zoig7)+v-&=%?nO55)&T`NB+8ZUIh{2rUN5d+g z^|k=#sRq!u0UJ)MXG*{H7RbSKpnup(Gi~7nNc-Obo9sx59wD$8`E0;CI~725c$JLj zsT63nLSX3CuA&D`YiAlfc9JI;2>A7w_X=fIjMea%S=JqM)nU$ABn8?IvsdK?}8xxRao>XI6f^svX3)&J6K>4UV{*g<&3I za5$Oar$_tkA=g%K8#mF^PgJLj-aee#wSezWu$YgPptVQg4S7ty7bCFOL%vU99bi;e zVy?GzBgIDd!%vz3yWqEG`JV(1RKMUNX5KA$m*LGFpb;-m)d~8XpSsoqGwJelgXqfG zsbuS`SEMKKxtFXrsi>%;bso8+c^~h~ey~30WUF;q)!sWW_-M=0mGoXInbXGh2T)02 z6LyWWpc7t!MkX>Sg1%tad;b<#H8HTUc{e`-egB4ydiOKc`2||CTj%33pTQ93fM6qHEgQb5DC87~)Wgk%G34w8UJGB2`laSTd6*-Q3M%&Z&8xVt9Fb z-!|*e+nEO zAj7qwwTy#t5;RLX!)P`p8v>0MIizYGE9hbYTh{D3H7)z0w+S#PwPkwDZod{4GQ(tWA5CYWdG;&r!eRz8B4 zDcQMs=HCI~8@K&{F{0gUq64tI0Gs#~Ak4Raa+VSv_oBM+0R_?gWqa4E&ExKA18T0VHNx%SOz{BB=k zJTPVv#CbK$KVr=Uleqfp(}u9$EP(BY1D|+`W=YV-l)wXj7ijc_{VxTl-B3UmPFdh; ze87+JHt&OOT-SzmTV=a#{aCSkAKnXuWQW-nv^_yR|9s6{C8hVk>>h-uDb1-A zk1HHHN~TKsN`Qk1?;xpD$UfUNO^ zhXlM((z-8E+zWnv+NYQoMEudff;k6TD87tutF7{3s{f)je+Kxo%I%?K)~4F zm?}O?V$VQOELN zM)reMfg%QMUqe5KIY`qY#{{hTcr(+y;>WY*Mu#~OM6v_~q?C+BpVy-3pwCc?(J^k( z%xhYBYsfYE{64!P9tM$p%V5Wt8JD#Yy;Iv6NMnqsj;#~XBOjgWZ7a7%PdsPO%^5rk zcMSOPu0@G%wVXHX&C0>yQg&~EFX)@eXEmmqXd^OHU92H`z6x4VM>MJfd(6#Tm4l^F4fr5cFW5=`JHxEjS?t`uZ{I&ZttM0`f z%Jt9J^%+haeR*Y%fvcc=-gjlBkokTd4(O>G2znpf)&6lvS}}4 zHh%2SHkycWHVQR9`2ctII=P2eZTWdkxUnF~d2Ij}w7_W9iD%3<-N|D%TnyG_5s51o zacXx?6>%px*qD-?uQXdpg!>1|k678oL)FvvDFN1ClehD|xcsfb$AhiG4)M{=`Bz3H zUphdGUinFc52lZofhXd7{^Qe61@}L4Ud1~+pU41(_pGH3>NjY<%_r`p zqWezP-#$_5Ri62dc}6@_)hPGz-aU5q6G@hVF+>%3zQns%ZOQM%$z``lZ_I@hKi`w0 zNX>`;UCYYVbUOE)tWkqUT6h&OE+EhJ!l^*hE)C6x`?<+r7A|f!4pz*On@`rTd~eta=`J;@e8vws zeCC*i+GzFl0OruIPE>((dOX{7cDgKSd>t%^Tq;}<*A+j|v+gxoXv0BW z3QGqlANOYf@8;-n?gBx^*K)&F*BRB0yeM)QY*2a>a(0T|-aYJ^n8LaG^C7B=h48cH zj}@Py#jC$woWbfVB!*o@!UPV<84iMBP0DZHo+NlCmSoY7jpnqD&V z3)sb=8+g8^D`@gkbjEl}AHcP`+QakO(Hiua&?wNjwddNkNm7ew$kN>-*vqA)(%6-P z!lI+yH%ns35JGz3@a!VWjMM2!^?Yn+V8ur8_%VD#xbY9>q!^?QVkoOd3UMZ7KrnWH_adsv*U-Nsaxw*M9KGWHdMt%d# z!9H^sM&a1B8$tR#L}@`u10y)*1lT+Qv8Fdbx$EsLcmn#c+#}iz;9koE_Y|o@`1@hud?OK`L4#DzPe}4o97lr zAly(|fTr{@u`K{pq9rwpj?iJoqcXlb_v1r<(8hdX@rL7krVQHfA3JJCVs#Bjhp05yoejs-Ezl7s-tBYem)JiqMy$R6TYTE*+0tq6B`rH#!7y z>1lrWpdWoQHAe78Za*QLtj&fEZRQ&4`AMx4P;Xy{GnX3H-6`dKq6%|egA-EkFPA}1 zisYi+Tvr68%0iEYh9^t5PrH7k7~?_^+Us2B)A96-T}?ZDpOeSLwv+Y#U`ZqNeit9T zbA9dgSf^_9Z&-q5MmojIVp!M_)#1_e^F7vCfFJrRP-0n59YC`SYvb{*o`$0FZj7=I=Z#Vbt@g zq#N~(z^Tz4)iWdk{Pt;k?Dm@h%~xT1OfvLZ(cKqRNM@BD4 zIC*ojWM_`HVnl59YOz*f_#%hC$L@KU!GXMtq@uC3G8uDVq9zBin(J`y!Ow<*Vb?4&yTxl?HkvAW}4-8g+Y9>|a-> z3axeP7lj-F1Y7>o?zvAbi6DVJ-^F$o_w{p$(`HHBCbQgD6dM)<8w-+cN3fr&zP+b9 z^N3}klSCgh3>mIx&lfk{(Irq|^?za(ILK?CF7jo}QaCA2(q%b?+2CYG@X5Y4VpnE? zYd+UZ{!#_3gcLowx2G~m4C}5Tge8V@>Zr5`ae1zSt}0B9U<;PR2aj08En25}>USvG zUIb*kD0?nrW*!@u@gh&CjT3ZRYJxX$4V(s2F>Ab|0q+6v2QB}K#Jq>akn#(d*Bx$|jU^v%Xk66ACoFs0%#;8Gm&?lUAJxvJ4rQm#?{Put6aYJ|;lD*)^KYznaFM zNa{kJ!i4-3OLZep5n>w2^TQr*dsFaB%PRXXCG_7~7KG&uHPspEtU6Vl>^Xft{`+vWrJC=d_=0YA~6NLtlN!y}Ze<&t)q40EggqDI6{}fy(bYKsNu<=`O{qUwFXfy2Mfv0{doRFc)z*yo@;2+jNTyvvR1LYkT? zv^_aoRz~2KLr?2GoqLjc$E%%~LXPkPL3TB@P;rI89_YUp0&&^2q#W-}5ohN4iH{3D zERv=>7+6?5*gjfX2?Sn%XU~6DiYOw#Lkj}}`gQQ9Hk1*Q((L-l(H{9*``E0CB3f!r zP-Rfm%#Xe)jLg-rO90lAnZyR@9VX73VAd`X0_MUXc0I2O?_&Xw za~qW8MUo0*eXCq*0`In{@I0_ZjV8ylV!4wh(g->#keq$Ga@L9rYB*F6`as>8`-?9I zDBnZ@#8)EJVmYQ61KacI*=cb(B;;dVeIR}-ibjqCzVrHi`k`HfkHHJjUdVWj#J|RA zNuWLYkixEN(=QNxpH4`K6jT+YPOo0mDAnK7UBZMoqA4ezMFW! znM=CiqWWu6>n!8{%}qdw5zo-&YBR}gpP#wOPad@O^z@|ias>c~m`?)B4)PlTn~)Ar z5bR6+#{95`d)l+H?#Old^!Sy44XY9;mjmBEomtsK1z;FtZwBQuGTWI?!4HbHL9-!p zx6OuwSYc&imq)ROz`C93Fvqwu$DlId)4sv86$9W9xGTmr(NlHI< zh~9`#PtuvcxZQ; z{s};{ZyCceD*4L6tF&Yn8!;%%Yy+x^D0?s<7V=gsB9)MgFraM~GDEDlHv#>fW!HGN z6@AM}7_Ji-c-zN|M#Vxt&)0Wb(Jp~mZ-^bf`FuSDSUO+zoSCeVKJ8DZq~3*VoZ9a9 zOU{C3)T9z7^z)D9KOFA(H0LTOe{pe+XzrC0qC~6`P!$*kRhnCfv84npz)Bcru~1T6 zKtuNAiepH zaurwL+#B%4x$)jq5cu0Dd_S@Bo{Ny7G8{S^7cXio% zz>{|i)SaK}k|NL=gWbl#w8v{2^N3fHPDc4P1lV;+7b|}7z=n+IO^b8}X?LwRx^8lM z_za0QmqppVR&j5Ntv?>K`Cb%C-hODU_~Co_^v%^On7wg zjpu{H_dF4BOUR%anGTF$pveUmMM;P#vtI$!K+^*>-`#>(*7aPQI>9d#B@0kx&f`S3 z+7<%q<+hc?&S#&?SUs45U-kWQ;Y@hCZ>ZSGj z1a#zYM)MDcES{373^TIGK9M-b0b94+88TWr;R(ozpqq{Ah0Ki#5V3^M-cRfSs{|ad zI67qy{gabFdO%~VGJwruqJ-R)#(y3VRZPjL0v-2Y)w38EwP3m4#~1I>H5NpY$AnDX z7_GUYH+>&cP-Ij0+-=HKJX%!3fF$yhmAfcbn;PhK&^@&W!hc`NJsiT zwja6%&*B3z*h|DZ!7JO~xIs1xTK{emM_IjoNX=nXo-CI9OByvT}?-1`4 zrDKZ&InNzbz5DqZuyv|*b}2JZ>rO+OV4gMyrR$ljz{m}pC!w?mtO;t1s`&<5XK-F2 zPH&6{pcC=kHOVpa{2YL!u2Z+M1Ma7Z1yci-_TE63g}@#I{Dd@jhbIBxZ%?YP6v~p_ z4y8&vDUkf8euUSWoR$~0}Jhwff{AOGJ`WkgU021q84MyWlcC6CCjn8_wky{3QaY#-jZ1=;B+=mLT*+q<_JyL5KtW z@>lH%5ZrRS@mr{97F`vowSL0vix1lrAjSFhWlV%XeYfR!O%RiHB0ItJA27Me7Xei3 zEMxo~3jY4h-!LzxcI)5a(XZe3i@y#q;WShfv>ANL%r@iUEFAf&#HByCgm55qsF1b|41F&`FHo)T>eJDZSVc6Ez;J?E6Qf_WSz%>-Zq)v5Uk$}rF z*rL2%NK6MO-bMHdK+p#Qt|_WKv7~=c?8&%a#C{a0f7O~ES6LE){UJ`@KY`ijX!obE zJ^u>HKb|8f6)OGpo5aNJ%igq~?z3^Jel9H8FyRlNzJC2Wou_j8gWvVUNhhIsp;9Rc z&wU&qV}&FqlYlPDegIPAW}3Mr-WmUApoGYg9GZUF5?(|`f;MTwF(NLOX2p5Kqw?Sn z*tUiMM(SjAc=-Nlg3s=s9PKE#vC-GDe>P^W>Z*l@Qerdv`VvT5e~&N_GCDI+#a~aw zRHc9Yt{ngTxt}mxk)i#c7X66Pq5-d)^@U;?n^%jxQpBIY}2TBPKIMTu@LaNz)v>Sjc^iO#F9xPz{7Am*oe(jIwpG`uZG z3mK1ELI$i7U35|gp4^!><@ZQ+(HK{ua0Bqw0)VeP?Ra<&Cdd@(Y9JcA z`OBoTtk7hR{uZ3}E)>%&b>`Vz8wsizrN6tc&S8+QUqOKU4%suk{noo}>x*vR#C~s# z`p9ykeh(0*p9XeQj|hxMPs8Wx)vF>LGKH@$ip7PuDjabcnzrUOCdEJ>(hE10&^4rN zN@LJjK4x<)hXwUS&PGO$4Hte6qxn7mTPv>3q$dcYjUjriI@Z-DAjCrujIV%T{Oh^Y6EM_|@Tq z-)Dx4V4jt=E)DS7Q|W(Yd5JInW`g45HOV8a+V{^|QY$tMrd-Db8=ve&KN&yn;db-P z{h;^A1O!{du#EqO6yJ+NN*J^fBz9R%2mdVO0v7a`d?6#FM;&|5nW&u1=+>!sx zy<*hJ=U1>GYJf=ou30kv9Q8GCPFwqHlo*jjvw&njHjJ~1%I0MP7|PZ9;p=t+g(cse zwpJ){-c(_+(770*?`j2F&I9NvGMpf?;pu_ojV*zGX9Qg3=-rk+wj8 z9~`_5+ueO9Y!ZL7`6DA-Ks~D&cLF!{&dggh_}ZMd`J+|SVg|q~g)NX85k^63_@(-3 ze~l3!XYO3gyHy&v!NGZy51~)n*Fce5(21FQtD|wG!<8;2vlX^qF}=j?P+HQ(WV0R6gtn8Ivaw#m1C7ck30#I6ryONa`Hs)Vi$4Hkwa0yzT0*X{#htsr>PZ4? z0{M>iX7lH7t6yvi;3kj1kWQnGeLk8Gw!%2F;7~KH4^bf-%CeclS{^JD5EJtQgv)Fc z((smC;8*)waAGyXn&`Xkl~2AfmEIFF+F#<#tXbkn5F|f)wcF*iR9zz9b+>lV0fytG zxBbq^xEW(_bEo+uKD?EcLelfW*2+i?fe4?M>goE+Ui7VRkvEpd3kU?(g#Fc`SbsE( z@y9vnoqN6*ByoMu)`#+EsMctI57n*sWaFjT%JGv^DTbdDc&W{co9M5cmdd9fFNwV& zclt`m2D7w_xG`@mg92vkr*hIa@8{dq!=A5nsWuvUnXm zM|n`D2wT_`7ah4*sBF}yhwg6tYUO;)iDY=x;Gn{}=gya-Q*{@wUMvQfrfVV?mY3|t5YvPuh74t^a@Qf?d3-g zW-IME1}zR9_HQIL|KTa}6Q98HV_C)X_pNeavgHEfHB0nY)%1h7j$NhF!gEKy<#By4 zqFs>m9#dT?RaR0z#cP!Df2fxT-4u0DRQ+Gwy>(QSYxp)Q2og${(%m5-APv$blF}$4 zEg{X2A|Z-&hteS_9RmnT2}nq%bPqlBdB(lL{X6G;f1I_>S?gP8FBf~znRnjziTkYGQ*T1d*^jy)^JX%Q6@Tu}DR+9m=G%kbSDNF?i7^2}!1Je2`)cz=%mNf8tfEHnFN4cxNk>%dQqV@4Xk?sC6BmJy7ppsaRusO$naL|E81_1YY=}E{ zrf3sZL-jDA_lc?;1r#Lp?n8rhVNJK)$zr>R%T8GZPJUO_BY{S}f9(#n?mss5d%(

H@iD0tRt@+ZaPfDZBPm?zWrT2W>y$|IFMAE)!b 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

7=_HYoP$BYVE!nEx=UAt%=LeWRShAmnms zO*8LbLMrwo0`3q3+|F5Cwx-mPMw8T*qQ!=WeUEnL^JBs-i$m>R?6^cDtkSGDe!DUF zEr?iuk3{!j;dT#sAk9H#!AwazJ+i~ojhDl(jX~yZPSH33LXu+kXfYH6B|?8a&k0xeGl+kbP1jDW^LE{Y|iCYeM)(xqU)b+7k0>|=mK)Nx@rZ`ZSJc9c6C-ck| z%elVY`bzEd1=OTX!Btjg#AZAScC{ZF4d&V1@0T@FFNJnf6^(6do-6= z#)smRgOW5%t7Z>C^3ybB0rUucNR2nz|F;%Eya3FoS+)H*Nm!iu>V(`+(?1Ah-A_TS zp7M29CtwAo-i5H>>D@$4uH7Ot=Jw>K^z(JRHTE(R1 z0T~V|0PxKzr$Zoqc@J>(Nt{zdl<23p;Y1unS-8H@7oYj8h1nn%Z%|Kh?$zFZwKfeh`y{J;W3D;9eD-=NGh{E>#l9J4N>cb}yaG z8G8T^_Sr75Io8XZ`)Ua;s+=S&-~Dj~F0|Qwg$tq% z<1lAOl72)1C^zw>q@UayynD;tQ_%KZduz~^i0ef8v&$9}IscP`v?BcJe2Fsio|s-y za++j4fu0Eg^ENCWtExBg9P0N3s9ZKire3@Tt+01$iyY$9-tS}4aY$?gIlkm6K)$3-lM6G?8mhBS{|^w%Dvfd%_W_|RZ`ArxpSjWusEy*RpnTP^9&y98pzlRO z_2#Uw8trFM+j_56SU_$Q5>4`Y<~TJyNuPxkI7yK&st24oW9_E91ug3UpO)xUf`McC z;`CDcxifA_!}j^RkCPXJEZZ7~gMv+zm58fyWQ3i}Uy>Akm(Rfj*O{s1z=Ff(R zXRtbnInxe@w4oGTeLb)0`_z*_3;Erm;kv{&GgfPQjQ2T;r3gRgPzV5Izcg-Lc%gV@ym;NH7j3 zCTA1PP2iVK5B1xey0pMWF>cWQ3AUz!(sXllj*yzBNt;h0vpGy|b1bVC?xRQ+0w|mN zv-H?a*XD@QnC%feYmU2o@r7neXyJ7r$`GJB}!wqam&4Q z0_%twzySeG%HH@mm4~7Vd!snN`H-A^+^w*#Hn+okTlGu=f{ z5*f(X$M=#r>AB;Hxh|9^R}u>+HB9FivL5lhTVZX1^@@(xGK|Haw=-v4EV&NJz9w9Z zq?h|Jj!!=DVSJ35o?<7+!hX&po;d27?M&8-B6gz+NNU=Ld~&x2CYQ8ld!TXjt?=Va zzp&CvL5T}t7i9s}oT#Hz6ceAo{~~hUqBJ-!hfG!H>YYXnFg<(R5u^oOK@*_L7Vm(YcvKJGqD3N$sJD| z>ZcTJ?%%!`wI}kWI<4>d?Jf5!sXX2B#^A;@sd|`p+e7BO&w9A1ur>BD90Btq`eJ8C zW`h)fldX&Spc7?9;V#=O#=Bqv7V1n#TP79gOASk3(xsx83$!jPxc3P-Z9{M< zhql1RoorDA0u6EWOKt$VV)h!@Os_WO`$f8Ly=9FA5L`7cDbWO=YF$BBaN?{+T@}ZN zC=V+r`p@dI;%;#JI}|)|3KGv8?%WRab*WX16%N|OY0S3<;VZegq002m4iA4BWwrsA zT~I@V8)ZHT!WAFkE{n!$aDB?{dF=2x`Vix-JX77?NepI2k?VqyE*)@wzF=o)>Pbk{URMIMk zTZ82a`e^QP*ve@?GQX?fnx);CD} z!luBpatg`Wh5%BKq&XtmN;vro!?@;7`q!gN2k=+jbo|Q3QcP!?3mtrWom{3sWPfrn zwJGB6&QAp_Y_~;G3wlWG=%Uy>Q&cYD`m#2D+F5FiY2Y%A@Vg_dANT(u^|LJtoi&xA zqF&Vqx?+EHCfVtk{e0=JNE%$#mhR>l-<)404aGI{c_a9-02}B32lA(C99oG`45x%* z(GY9ihHzc~k$>X~>CxzZu@fUc3%7%Og9|;o1G^sQtM}`}*NsgyYJQ$5(f=-{bA|`` zN)IDM)FHD4IgCwB5--7V`hepjhc(USB#`C}5jw}bmfnz)yR4s&vVyvIGI12Wd zGT~70n-4O)_-48ka5%Upo4; zRXL-TQ@;XKG9EV!AD@vyZVx{Uzu&`Pq_p~SiSqWL4~0iB$L8krZqEzK&J`uJUY$~Q{fA<5 z{bhEKSZqDQ{*Sf)7}HM;y&>Y^M%fbMT z=BEO@rbxR?{O{|ASLqtS0Dj|HBmFu;xiS0EVo`{#B3D@Y@Q0AkUbo&YZ&0shP8 zBQBN1-%F`4M|0=SBRDz)N_&Tm1LFn^DnwHBG7+j51@-myEyXRDv1eyz@zK#U1i*4s z1{D?cJ#}_=_K=0CY3@n0#F3aNK#}akKDi1G5GFXobsv@SOZc-60W%h1;1o#6yb7SlgdA^j17S}^ayCQzFnN3?jG%!$R}~WLPka&6YcMe z2B{Jfw3*}OZ$kTN`oxp}xxD0PhW#uk;-q*xHXHY$MgD2_mPEmSZWUnei^5~+L9|Bp2Rrt-N&|23^DS=W<+1F;r`kpik&3LF zqge~V&FRE{{|X&Z<$&XKf9PGMT_x1HH1M+EKAkCYh78iC& ziwr!#wnl>I+Y=T?3{!6Z{q46UAnEHmQ6xN)x6kY^_}UD>dIxoTV@Cw!VUh7a{|BsN zFoZ{ASR;?g{CfdBui!pkoR=d1@m}~$gK7T0m%wMq@94a~b#2qXU;mRLtc3jg3iTD) zHydEyOZRV14ICFNA^da40RQnj7Vwq_(SLwj@M&B4_g)MxFzQuG$5G~Z*%xpu=Ey+F zeFK;*B!LjUhuCW~_4RN~KNyG1#kB`yh%a%I`K%McR#yC-W+5wB_%XA=kI!D`it*qS z=*f}_>G0U9WiGDS4fj0XABER~Kp!cpb88_S;|UPLY8LBr06s4fxDbsww}VNj07BfZ z_1srPn*pJA2GicBw$(*#0crG^A9HWFEhse~g1vVq*!1QC0!-P0kH6?K8?QYb zCZ_)|r4AR#VhtNv1-RjY^{L^;I(S9|o$SU_496G2L5itA49$wZK3 zam&caz|EBtnhq{bw}gU56rs(|9ul>6XSxWfc9)Or42UPV-F0zs0STeXcvPwdO#@lvB9`50Pu|`< zoRN1$fQ_eu_&0E4I{Kub2l9S`aj1)^j^yl3;bH3S32aF#w%{`84yV-0jq5pcCd1H# z-S_f9(^Tem5YKCk_nK&dS~)V2y3W?AqaT1R$PX$iD$bG_(6|_@38_FbUU*q~lYm&# z5Gcv+7d+&F%h=+1De&>L&Ff(usTRl)lEBsc8vN!A&ueVfZtK4~VUTASKLnIMvCdQ!4JUByJH7+eCG)Z&Flxy)4#Ru2 zkcZnRwAQsJdaE9$*WpHn~CLkcd<+xrS^RG&U0ce%~9WF>%L6C z&!{pNk!~{|?J`*DS8*$O9lyybxWP(5^xZ&>+tUOAi=wdSStfd=reUn33S70h9q~*` zWC|$&6rr~lHOlzHwmz&`%81-$1BJMN_R>8BLKao=1TH2AVUt!&v$aPo)Vok}amv*o z1nD#IU>;IL?g&572APc#P?Qc#p@v8P0NBYl)~*&?M@~D~oO-{G+hYZeboh1&&bDlN z1MUVFsL-!|1a~kXan#Y!39#%BnK6_>s%HdLPSCO+&#rMI4tPFP_?&JCtW16^{)`gG z=OH5$SZK_FfRA#Q+dBBbP6^sPq~AAcC5F_5)X4EQ9VYIw=6=$hIX;+n&M- z#LnR1ieqD{Ka2+Ee~3q_~&yx(5UN+JM&6{HCX z@2R}HW9HU3Z+y@LB?&?x6HSwLQe2kiAq!KM_ONVdkd_UJB7da`ZU!wcam7)stz{4> ziHlx$LrJJ5aq+9fDEI{9?KN>_OocZ=j-)!yHawIP^%_Mk(7nD>#>7z-6m%`Q1jF7R zgeBpVz8H6?3`7Vdp{jJv%VD>-p?$aA_u+uNYOWzF*^ax#ZTUgJU!#1my6=yjzNV&z zep1A==%@Bx!X$m90en;kc_xAkP_YJ{qm2L@QB~|AKr)$ut9CM7|_P7Ie1YT{RR z1k6z1-w{uNO((n5;`WU;fuZq$%0VSm(xNyF6@9mO2iaOU{sb&x($I9Nd)TDOchQ%~ zqrwVJ6`&8xXrY4NWUYB|-{fft`nEcO5nn&X?y_D`al_h>SzLqYXA93AVHXi6x7hX6eK=&I0Q@K zSRjuEkQ~oH=R%I64)oO)y+!NmjWmyBc9*K$v^%~3jao3k{_@wPbR}6#^n&PlAthRY z8<{oB3bWEpVY1Wv?FE?j_xhP)4gnW+BR2RT+LR(iCL{b=v?!r1{^G~h>ruqg+90np zo(0Gn(t@JLyHF-bSBY$9b^W_DB?97eP(7q6!3>qJ(7@!+>~)fcK3vO)o;D zM)s~FzyfMs)_o#1R$)F_^0-{%8^H$YQZ{Ag^j?6`BP!#Uc;b`5HZO(Zj+0!NVd2K4 z4iyw}uRTxb8P<(O9Hu~!%R3Wb zx&QuzYlsU!@U3R_@|I!K7xELNvL!z?D6AFeF|*UWN*c-#_XF!5uMXv}9{Wioe0sX{ zjz2&Yr7~jN3QDktlw8~TgG_QZ$-w)=gv|aS|Jqi+e!(%bd9RO-*XQapWjM85!qI5i z=U|wNhC_YpnGEm3bp$pu4M~0Xo%=3_JUV(gEdvh0njhJM@Yrv`Kk##q2^KTW8)Rl95dB;FbV-@-QGRz9X%ND0 z0Y__-CB?*RrdfN=G(@OG*=dt@bHMc|VHu+SO+(aVBk}Xb72he?jvqlp3R>5^#5e0Q zB>RJY6>&L#L<%L_V1!Cci))fFc53@Tko5Ni%|SZjjosUkb^+!Y&+_uy) zmqc(zCbEy`@yC?K;1AsDuPon3FHsU!H$*x>M=U3|J}(UswiN@<#g`>qE%_rZ(D!j@4G)BY6LziM zYR10hdkdSB6&NAP=VLA}5Ujr(Qu`terDQ$iJH_;x|i z#+}60AJPUz#wWY>Cb1$Yw+I)qEY9=tT3i1ZbjLnqFdQ#-3?BmZf;AdB2|sFFrcYyz zC|{Ne=o_EQs3Zs!t+&_b&JIQu3`8&|E-xX5k2R3IMxxic&vS0$lpR^0^>j!^gy&9B z(6Bv`9xd|h`r3kB1uC`iBDU=lKt zwX^ysF)SM%f(#P@6#fV}pTO$pUCA9@T0_%_7;eGq(DpKCpY6sx$~3$#{Kq|9tGINC z%6A&MXms(S5Of+tsW;KQ^O!@G1!YdQ3F76skh^yMJYe6s--oO<#)^}NJPkB8@5PO& z5i9_@DxZu|Ln>%NEFeJ0?lF$>zv=^`x?}zMY(=Ao_3Uv!CqUdK9^~Za@&+codgyVGYv7MJ z^&uRzzT5mx>$9Ps2ja>`Z}mW7J2I2vB4ifGV7w*ohICs$3tpR-2t^gMX?lregiIX8 zziF2kL)_Ivvxj6%jAo2@fNasDO^bkMvvFZRKvRj=8i0FKuxWzmwQKT%2ny~jiBc<+ zrURirxZg#1Z?0;Yl3s@wGP0XxK#zb;(h~eMFjkX+*F%Onu*z#Y#8L%RS)?Rs-jE^+ zir7b)yu{;vuORq1`Beiu!$ipUv2lEexuV*$z*0*g^(-n?gCh$CXy#@=m1+`h5Of8B zxyu!{)0$UNha+%MIC3H?m^E@@krO#dkKA?ARD}z1O&`~x0(YsATaP z6gMhB-T##?_nJR87BA*WOJnGov|#54leVE-e5)w*b&uHH73+?UP*?h|}avV7V-3X604d-PcAnTEjw5ccB2Ju>NO) z%24@+BCbcC?|8OO_#n8Ig2epl;L&O^;a@g7Gy2qTlG#peLbl+!K zZ+pQQlWm$fpQ|z^LM>x{i4?V)H8q!oeHti*>2Y@kNmiQR+Aqa-mNy3P;bEKxJL9l`&+ z62aoSO*v&7P1lFn>-!iwvN|m`h(&hSA?98g6&Kp6E&aR3(YV}eI0n*Cl254>ULKt$ z#kk_+rO%Z1!dx|BZXuDh>C|g}+XdX#FY;V4MGeJ~oTHT(`?hF|hA7v9XqftDj9$fz zpr%$(=ivHMO5JK4X~3DJU(k+TVor0mjYL2hruiIcjZE{9mWCT4JBagi(g* zBn&*3VxAI4qpHInOQzn-+UXm%dXqvQCQ%TqV`}=U4NLD%i$DQ7LAP+N%aas zC3rMc`JvgET~Vruhr6yA1{OzBI2fq?kFBcB;#t%hzZXf6oVP()1AQwyA!(FORmrQP z&-VKR1ca2In$DHbo0H=(Efh(xh*51Pr@-d#G1!h~CVMv_k>t2NBnke3JM%6GzxftD z0y7q+2nAOt%0d$nJ$JH*M4Et10#Eq!wFL>ke$G%5LB`g8cMr*c61Mw_W_^>Sfg}{@ zUEeaJX1^Hi&{Cnd)-<_|Ji}^q3w0RA;O$0pK6q&u9Yt7))JA2*hbwoY7f`NE0cNbE zJ`CGhIRdS%(Wr@qEzKhyYac6B_GTGvAghry);?+oK{d$=F~s^%^3@NXc^ufZkkG$?ev%Rlt>h+} zzh;YUjAj;CXkCq>-5H_=rRgof3l+pCCi!M#<#M!8GfXgKlI8kb2z}FSS!jS4 zxppkQ52hwk4;DWbHy==&RdQ7btZQ#znU&P@Pc6xHu{Q7wM$370cp&dttIystltNk; z#!p4d$;P!i;RruApBrQ7v92aZTzJVHv6@58v*}4_a2%B%*{Y@gb)ydc1)JtCdKW_^ zVeW)#(5l*FcO?|O3Bm!<9tgiNaM2q;4%Axlz>Fz;BgW#eAALaq5OE zT7=bXNnW!om3-A*G2y|-r@Agfi=c);o5^8b8p+`uwf(IloZ7gC?Qc^g#+MIXP&eK{ zrSKNK1n+jp3@T8A_FeqxXTYoHF!7(Ibe8{rO6ld}Ce<1?Q_cS*IWx?o=jG2_0}mQ_3a6?8Z0&Ex zrK|OH`}-Oe<(&u99$O-AiwRn~nq43^v=ijky#^WPAa4L8NpG|t!_EKv&Lbu}p>*f# zVtnqqUo{?owf@{i^;I&w_9d_P&4%hY-;kd^X=8y)-Koq1cGK~r20nV;=lfdisRG3{ z@Uqj|Y*wfM`g~;ii9q#jPx>h|c%9ju2U*`>)3WrCHZrOEe7gzf9t<>xlBZGHo-OxD zbce$89w;&1?f{?|A0HpIM;RSiQlqKG62Uh19*9E+aj~mB>8Es<6dheYsBI(XMf$a@ zKIi*M@fzZ722j^IzOLb`lBdkm*yXzkBWoJmDJt4d8wB*$ZQ866`>sejg%)%86#z{1J` zv#b57ey&%G4E2H~4-@+YLnr@wELHdWd!HXPl-h3;JMK)_{x9<0I;g7d4FiQk9Yo;( zQqqkA(s~dir9(iF?(R^!JEciBY@*gCYd_?t0X{`o@6Z` zl9&;IGZ3240aEoI@apLS?%mnaAV`lAFZDYC^V3}QATaYXpR6f!2x3RE2jQ|jv_AVl zOlwFFCuGwp6rZJr-{Ll-`V>y2IuaTZ5)CFa-N4~-r~%fk46ts3mVipH3%9Xa$AZ(# zqW9BEb8-mW8=!f4{PWW=RN^#2hs6+&{l5D^k^Kc z9c1wijZ~QQDP=7{Q(9yp>jWnOP_zm#w#Z*N5YYozk5aZIZh|0P@3_xHtFD(X*7lLa z;f!DcGzM7*!4~I`IyMkFF~0}E*nEDqg)4y6cYy(|$}68-$qa#p{8xxc4ubM(m4`rP z`?wL#c_1P>XC2+Oop&}JOw5GIb?Tht#vH%{mYaz9g0A%i+rAGBg!7#+#Mv4SVkXx&Edk zrD0J?NPz%Ddyv)MQb#6MdUcBMo#BaYL%%_1V~73zQ>Yz|DzxzL)XuA>xhn1nt^SMWyV&JNeTrY zGgY6=eRX?(&|p@JsJhSZ?(Ro2Lq(R9CP|S z#kbLq#Kon`Oj@%o@*ob2i)ffw-gJHWN%6r^6g}&#XG4d<&vO|+VJ#}JR8w9id~-YF z8EgDuEA@&q<@%<=<7*A6DiI>H%W3S6O*2vHF&iXLdYYXa>8@l_lzEp+#%_muAItF` z*b;e)p;r|!hvKL7pU>C37C3i)zF^FD`IyAQ&rMx=RZ>y@eZbs&BsX>b<0A<0sOISvCjb)CF}dW;#2b!7XmJ0eef?T0pF!#<;8kY^ggc!!T$c|QrlkC*^beH2AP z3#c)Un*ae9R8{R1mF0qTJ_d*^nj`(Kewomuc-=_B@wL z`H#`2LHBtFS9%Hb+vn2vt|3d@NbIP)@spJCE@Br9cDiv}a?da*J*eoV;}u3g9#Z(} zR@`F&MekN*-+fT_whA|!WiA)CWPXHF&6jfEy%?Y*iwcObhu(m9iNCu^gM>|(YDG7R z6NxdOKWEmo|C!HXkyJ|18fS$9yNN-k@pvAKUUqgCAiJINFJ_*LhjPV0=OZp|XmYDWK1!p_D7y!zd+3dX77q7j+eBD1YW z9F`Ddj1^*QlnU--VSlv%R&~pQQXJ^R-Zpdn02p4bHx${uXBlcKaZ1c}78x$E`~kZ; zl8yZ(w&}&>(krEMg}ZB0^QjdTzbF+Snwfu{wKi9LU#V5=BysC` zM!pH|oy5)(RCGKt`-m;mo@5Q)h3y}&Sh0fNKczty(Gz;5F_3w zk-rM_av6BIof-RHBydHeuIeO^KTCh;j*5*(#rCjHVbAQ2vox)J0{fJAw6m zC75!n(I{Wj*V1r_Y$U55hQ4lWz9xbs|CaDUkUC*6>g&%SVe7O-77IZb>1{u7t(1T! z@7{m#PCPL=!MCCyP-t!2S_V4n4C;}Xh9!FyK2)MnHWPoUr__&dX#xX;kv15D6sSgV z+aR%3)z|nQU6_9lw=2|vj%wbMP~#iyNFH<6I^e)|?5*{mYoj$X9-Nnxh83oaiZ!0> zI;Yegm`cSD=#pbfP-F^BtQ;z4jk{xC(IO*1cJ^xhp{7@FC3|LCu24V5{&Ai7>PjSt zLNGM`hedpRG~wg>_kDbhjb}nlopyX-#P990$ONCMw@^MLO!be>9MSoF8UZ_A7$q_1 zd+y6ZJ|(}m+?yNFP1NI+I2A77DGxn=Hdo8Nu^ZS+HmVhROAbnReJ3dqWd&0J|D0&( z<}O^R{f7k&LD&j@Z!*j2-2D&sjIx2~`c6nI6Vl?;uZfUt>rbx~6f{TXw&`Yzf3F<5 zw%*n}->>1Q!Pj@UU=X{zxc5-)^{mC40Z@J-c6`mC zM{-p|@Jqj<`m<8&wGYB+ee7_d*de5vB1k7<9v7fIAJVuH@WfnSL=Oey=5<_~n{hCq zG~c3o&-BTJ-pVBsi!&{ zNb;cYOh}EgrKU24)zX@P1_!&!%Mf`X!snsm(!WioJtmSQ^5Oi!cU2ed>Adrx2P)xH z!L1Quts!Y0t1hvRu5{t451-s3;r6UL_goH(SUb9UL5#<6-G!kNI#Te(-Y@=6s>I8Y zyT)A_cI9-j3}Vq?L$-tNL3B9MG=VywY2wcK)8x#)S-xES{8H!B!Ik@35cek6eqdm8 zBq+*yazVD8mPD1BDn5kdYqrANV-&$+TCsiO_lq3b>x&NGZIUNzp6LeekUex%tc}#6 zNsw;5bD=R(8LG~PYJi7)Ode{9YV~Fj*+%+j8Atu~kqgFrUzq^X?&2sb1~n=1m_(TQ z3m*aQPT(0vO)sJe^N$SpVjY1_D?oPD;aS>A5P65}h89s)WC*KHsh%%=H8E`>@k8-s z$R5f&(oDGBb)FS8+I_XuaJU!zI}?sL(_B535xO5FE8T7f7aJmR^M}vAAIbGBSTobA zX@=)p@n(+ha0jYsk`^kEU}F)(lB#EY_9TFV+5@sO`%)6T{KO=BFOVJ)5wZ$;94qiD z6KC=i;|iq-*L=)tu~m!4l&A&E%Hjsvp3eg`QutId$-wdV6jEn#4nxecz&%4Jh(4v= zXIz1xG4j%nA#h@|Ol>z>RGHLZ5WrJhIhEVYC6ma~P2qKQ;Y(@yqtK<^??o3#JmM!IgUtxXS^D7|ECePNpK- zEsCg&i)i!o42&3%8?^mul120(x8ZtB%zBOrzFNr)%!bR;YyHhO8ke zFL>{u_8#-ir`{r^a`N>f7kMpGn1Tt4o`nz?dmRJW6@UQ>#@L{oqud)36C_Yi$grKz zjxTSlx@MrBs2Q~t@;rtCk~L(c@_*JB)vW#qtT)-bETM%$JXhP(Yurt;fsg#*^dium2dZZ=X~w_v?q3j^X-u8TJcmZn@mS#+zfVlY|Jxn zg-G`_hd|>mICVykl7cMWQ%M9OIgz$(Jv3Khh|^EICFwhvk}<&p#R?RBweNp!e-J^3 zDa%ATd?$yHl2%T$TI}gXrRt_EYK)(DXeWU3Zq;YD`4D2GMP~8>HI+tB z3qL@Cz1PJI1xsE#p3#*6+4@WYlxJE*Hka$&>y~WZ`@HvGa(Np9Qx@^L;s0Nb`2P~05j^alzkburtE@@OWYF-c z-#u!XQELu;yeU_(WkHy(rM}f2e?s#oBZmrEmwvXZk-nO*qgGl_P_XAz+DiXLwytdo z6*o7xhPyd_su!4tfuNcJ9i7GE_E|tOFP2SV`^V|tQ9)qh^GgYK$8+bFkxdM!RM?fQ z`L|I$hHBMq{{1~FPC%`ufAHWXpu20yQwjT_BH&0wat8=?>0BCFLHm2rI;mhf5`_s&-FlMPWI$R4 z9TSrzP><+LhPj~OvBN^b!eUEH**}2vJCMsBW8g#hM}T7k?rL+#Pk($mc6J3nfB&fg zvJ`q-S~~!PV&dQ=fyU8Q^NSkA?+3Z#g1EH|sGrjxGOJgZEXn$G+}G}BLNY=BoFT}D zkg`Nv=Suqh+-60=o%E1}x;O-$DbyY0zZqPv&wrp!{Of12(ad)Buj0~*Lx<^3&&~=S z)16adW^Sutgm3?x$yjEx6K6gOi-=IpfJ1@43eZBQYAv)C)r)I_G(`=TCqV$xXJExf z0v2XEq9$y^!B){)90M^_YaPzONim7SIboj(G zc?*wg#R>7RRO$cbFEK&V&m*=*N-{K1d=8P?c_8C6Otd4=)rhG$=2YupF3f>t{)*{j z%U?HPn-SauvmkU{{fu<2Ir*DO?`n{d$5Tm_Ar*h#XAaoTqA7Qv4?e?Y7s1ved)F{h z*z3Lz!u0G|f8Gyjs+LXBs|28UsLAFycbm1(R-L~wSzdRvYS{Oj%tktBwy?@%X6;1!X2PM#FLIsoS z&s-_Yhfy$#mv%M)x30VeLr#;`@;!O{&92zaW%UNS=9zwO2@n8(`N2-x?XlWjl=0z2 z8rKS5McOj&?(-o&qrDNquE8&xbhe)(%DhEe$+gU%*{8cs{|RfUPe%Oo+o-ARvZ^Y_ z3yd*JWt(bJaWpCCpr8g_fA4Zg&HZc0jQLcbAD7XizR41ML$7gu>CT){z_ohk)icLN zmxq5=s3YP5fWWsFH*J+U&8uUX+9>Ti`0h=N8S>inOJPe1b7{BuYgL`>Y)})QB(AHD){*1v~2Mz>E z$7$V+!Rfkd!t1c^XO;3*bBSPM`a9PXfkJI*HxIQTOiOpSumY>kYu9%k{eD1Hz91!F zj|(K{VP-k01pY{?RC1z#Qw#QEE6Q&kHF)>*SGcPioU!TD6{T(*Xr&-nDN3V7x!O%Y@Q_Bu~(rkN4#*$rlb zDyZ*ky3m|wU&H*=BX8?o(UmNBv*==VVWgXQ)7gUneQk=fyP9upF#RjuV#bjE)rG;bi^;H?%PIlJHzY8nBn)jTB@25 ztx1mAC7HDHw^eRM-buT94t!sdph@+w1-O^Fxn{R_KictFvIAf`9A>7n&3clpZtU3i zW&b`?$3>l#c6_VVb<-9mw-WoA+)rQB=&Y^9XT!a=W!7k1S$-61?WvFq9g>fEpBH*? zyEImMu2`=f+n_lu#Ga@khU@m-c(VDz#EoK8|W4PY}RYmF!<0%AO=G>1>sV%297pN3>Vr72~#h(jV=c z*htJUzkcBxB2J+cICD?os>!L}UH_^bVYPWHI}lx1i>gnpQN^Tql%Yp(o65C3Cu!mb zg=FA8!yKt9yulw?x7L$Ay)O$QKXx8pV9enG=m@|}%=jWNH2}{aii$b-V*;nEnXOSJ zlQT!BrzikPe6Gq}r_o;3;(6+86Z+bE)vkP4^23_Io9;aCYE9ObX|vUQQ#n68=2EXX z^tqnWC~ksnb(j8HW40G1k8K0XL=B@j7#|ON(!Vy4#ut5=AI$u^LzR_X8XQj+OVsqu3nger{DNLEOtJ}q;ABeh<9{;V` zLSp`G^%kniF8%gBiz^R1GV0v*<^%31GfB+{7?i*U#Pl)sZ?k%Ofn{+;N$B`dfnl^1QQVrB~M?=pqe*an-&01| ziz8WLbXSw*3~LmUjYyrJaT1k@)iP8SlmR?H#T<#cnrkidKygEkrcG z;L}&Cnu23OcjAnsP>jDuq_3y5#p--p)>)k9Px{+ih)_L%!_^dLu|DZ+1R7|pMpVm0 znrJw;whYz!mS6FXB^6J_AkdA|Z(TX^A6oX#V!VxJb}RZ>2)*8|aDRAySj}Cau2ei- z%P43in0?o@T1}1etsyfvbWTVuIh@?lqCs2D>-;c;Ou$um^VpxA98lK+kT37xJWhYq z6?<5>_~M**ND>}fEkqI?^~_X;E!=yQ{xMCK(Za!&pIH0wFjNie#vmbh$hZk%i-;!r-ADMUQ6tK-&rrBN9-GD-an;O+t86!4wfse?j4oud zPQ+N^afJw-`e0kR`3MKe)lk&lEV#=!8T@R>US5ftqI0>1&$TB6xUKVzEZU}2M37Qi zH3HO`-**Ah#J4T6Q4&T_&m*wGa9Hy=Iy9!KU+d{aumLrP2?|iE5WQ`Pr%!u8G!cAc zsVxI$9YtQw%FtP|D$mu*p}ikt%;01oB#^G!ZYHW0>Trb|!n=oN?*njrzK?wgC zXYM9{RTTly0GWuCe!6{ZNchHh>b)#rP@&}$QY;0eJbcz2K0X;fow4#)h1(|kyJS|Y z`dKpbJQRC{JHSSGFI`WIWh0EAYD-XbeKAq2R_*oK%9>31LXQ_)C0`WtUXW!(YMuPO z4gSJ_P%r8-5M$rRD-*f$yL}bf!24akR?qz`U#FCy+-na-0}qs0Vsv+uczXTnHLGe4 zEVaK5i9KI+Gi95KHx}HAvAuU$JiWO?!-o5HCi&iq0?&@#@AE5!>ra6v%m1Mzjj34k z8ggO6vB6ru!@)PSD%gj1O|%^Cti4#cqEA8i>cFAbLpvomk4D)rA`hu{CtH?Lv~GgX zdn?z%>d}8!`Zei)wsVZf#deHgJx?ZmKyz{9j<5Qk6+sOBU9-d;EnaheQ^Wu126SL~ z@-<#E+VATEd6Gw&&$~x)+IW!1wY2b8E`GO=Kmrab(&Y#rPsj6K#s9l9KNWX20x6C2 z2*qB`=N{2Wo2%gOpIaJ*xHw)~Jzer=;?0=y{GS|A`9H+jlcVW`{(faAfBqFvK9|0$ zFzuHfE>!>2-{1dJ(GM4=x^qYRcXQ^v@rdHDodfJUs)qotaEX4 z4({DgCGY@bm`*i}OPc$3V#dIGP7Z>CLJx-@iG%)sN#Kfah@Siw-wD;qOYR34?`c-CT=9iZXSnp<-P^qp_A$04My2fSS z8;f%bLqebkO(tU8P8A8~(j#)CSfoO(toYZqDuS4?#aRLu_@5SD$O_*s(3WJvwbIEG zbWlSx4ApA%PzPfUdSqneJs@Jv?@z`HY~ELP+MZ^8w%i*7V3Gn#S{j;c zho$av5ZeoEWxKc-ABl;D0zrE!++L&)324$s&8gX+Ez2Tg)X&$ybQH zxoIv!*tq1vnxRKIGD(Yo;jjl(^D-%%#wi35$=R;) zSbU2H474sljavf$4OW^z@h#gNtB`nM5gZWEiO^unf8+sigLe=#O%Sip^De{d4#>fV z;0_k3vfT!}Ffu_eEr1iDW%2_$9Q(zMk#oS}F#>To5D7AUK~~LbEh^B zJy7l=j6L#z+A<=O9s~&Q6Ts&%A)|LRdYtUt@jmtfiG4uwNcai- zU<+xz2-5rV)wVOmk+)UyDnhcj;FFKn`&|D z!N%B=^NR~smFFP8ab+(}(Ax_TX8l>zN`V}7{s?$5Fc6d6KfAHy`y^r?+>E!~V_6b7RfI@C_@A#v z-`PgYUN7u$7H%O!2~(rgyg~vIs((QDVi5}`R9WJ9g{xL&k>GJSq?#`apgk2X2w*sO zG=WP%q}Dl3foX;exH(1FkbAj_O;KkjMUgztcRRXwB_4Y2ej;)>TvsuluK$21Qp3<4 zxhLGa8V5>Lg91Rn;`BOqL4^JS9~)`lHE~lAng-k=ZfCat_ZDicX}0s=9_J$t4KG4q zfiC=b)7B#i0Yl%)>XNiOeIbJM21(?#_tmAnHhS>ZN`ALrE5^zW&_l-o32rVBGo9MK zk{xLQYTb3;twB1lu-?(rE;((WC z@_;Cjd||?X8iCC?%&6CP3b;hd?}TB^zBjP2;@p316)Qj^vvW&yk|`Ns~PZktsj@%|A5q!HbQZMUShBVJuB1Kr5# zl@BtC5!h&e-?9b)%`-r_1=9Kek-nEaDuoYBI1faGu1H&)fcHjLi+u#<3^g5wzKG;- z01`36{Uva-**D0{FOG~9NPvl;Q6emY-57*+%ZHYz2<BUoGCELqcp@b#71hf#3K&c7=J@$zOA@U1UKV%w6 z))DmVWTT>A*{d0g3!B(+M0~+sP%~3FInyVu!FEOF(abV0@7y)y>i&qE@%khvC zZ3~UgBHH&`RPwb>n|A;O_X!t@+A(-Fqz}ovqt?m+*PJO)O)WyKM=$SjyN6*SGPQyl zZ8Y#=QE3MUP5}=DTGVn2*~+{7zwh$Td(pfW5C_&sohb`3?KCjnRr!3k4U#GxL2Ow! zY{qtz>rBpDn1v8DbIF0|A4ve?zEEQ|3@zX8SU=v*Xl}#sfTHXKMr*fT=7f~BWYR=U zIm!dg_SN=>?fIp}fcGYA9fqa$*mn%C_o*H^iorInKMo_s z$s;xV`Tl0Cs}4po3r&&PH0NnWF47SF)~ZrboY>_y!yuFmYIM+YaT@xvr@C!;JO`Bd zs&E{WyWF_G*0M1OZh0G8cevP0G68!rZnOQVM{8Hdb(FT?YD-uE8gZsq^Ue9NKXtfd zGao3+j+0?KbQOn3&crTC+UzBN3$*E9rc~BN0Q$5p2qO7gUG6}BmXeE04XfY6s8Ml~4$Onm7$MaE%w-TDI&;az|O+o#+psZY}NL&YPz$&~W- zUAzY`R~Ko?a`fJ(J!ys5HXU^x!m!_;PXisMX6x&a1Z+?ROq{M0bvpn@nEo~t_NX#O-Sd$B8B0DHSv^Y>=uysozzD&LhM` zSBM=8q0u0Kv>mV@2VBnqK5WJnD9LEV2tJbQDV|~-rtkR&PARkC(^PW1xKq7*zm~y# zBx2x)<%>}A0I#bC&dV8I(M(lBY5wn_r z=(l@rjT?7sY1sZ)nr%G>6Tn~)-Uqo0QcQ65B=`b}JHcW7l?x>q(~RptCJc#Btz(25 zhVl&k{bH|>hYHfR%+D_YTlrN|Yt=pvofE?5<_*9Eyznkxu1jyT3a<)c?8TcOY938JgYyo{Qy;3#5;@9?dsw}mb=%hqdx31 znG(XD>6bn$T=>p%mnxENub%Da`yr%-Z$LT|4HVZeGexaA#<{P!LtG!iwoBd}S4-zpx z;P|2wgm=Goa-3uo?Zy24YPUgtpK>HIpcLXYlJ0wTKM4?TJG&E@(d0`xs(?NMD41wL zF2Rdk=U|&oH%?ef50n z*}H`wl<$5-$E_4g$4zsQHPnCYD0ww5XHqgwQ3AQfMm{0Xgfkt!sp zoI{mdenl59bu=eD&ng9$a|UQ{HbCc6iW0*HST`;H23#zX_{i#m@04hoNf_1eAuA=5v3+$> zUD=;rWvsn=8u6Ve6d%3Qe+LTCzUw#+?<5HJf3GH&(0%?;vpg~XT2Wim%sGUCLOTNErGH$3A7>V27CQrQvT$vESMxmO6uvo22Nj3G~U}-o0CHI zZvk}{*+Vzwa+AJ0z<5UG1hg{=570+aA2{X%A4##P5+G@_5EpH#olFlh>3{mBtjai- z`4LigE~YO~f=B|&f3`-)E*=3vQJ60KV?uR!{R1Q0qH_kt_9T;j+>!b$YreSmqK?ygtRI1LVlDr$ zsJ~rA8jl;W;L&vPTA5i}!GvYT0`o?>(4gGc3n>j|D7oL{r_` zsWzIV%%~XwjTMWC9;ny-c5(r%)B`|*Z=MQ`z({Z+T$DU`XjP3-FR}YQ#ljv@$OmcE z)j*+r?zUN-piY@&KGsOo>}2&V;lT=?&I&`U{>naV|m>|E@v12eW-vD zz!)Ir2BO{w42D+E4%TQvRjAwqUWYCk(6la$Mn}UOnF9#)t&vl0;Jff@pbiBVY>#y( zpCfd7bqe(^_9+kDt4~R@j)-$Qt~UeVAqPktrJIF}^n#GNFeNj*PV?Lr*vQ<;&H$Fs zoyz-+&UtHc-5H9dh0g_nVIy=s2yI^MUF`>lXTT$92?Qp`0pSmCm>57R_1!*`%86>% zDvT!32(h7-!fG7-%jdUO-nAi-oyu{!cO3_kf(Kxv)bLz59Hu5%R403J%J}gVgRYm1 zg?LzF`h17W^_)&A!V)!lg=I}CU(uCSe;G-{pl7?o7>q^nlHr*L#~vw5&hVr02%n;T zLk-$!4mk&@WOkv?+KqX|Dfdmq)gRQRnQ`4bddh9Wbaa>8XnT(T4`jy=PHS*p%Vhy$ zaHu?hD3qB7KnYD}J6&&q>J2ca?zQdlssb@6i2V`=%oWv z65jIq!(mOOOcAtjK&d3>!n8Z+0bX;UDOc?&O#d{0BI|n1U2BMIp)ecfUqXAo;A^0;CFgs)M!AzvFbk3KB+6hNbm705cAQ2 z>Ty3**~{iEHpR~y^h&K)XG*$muKW1T`!lWS5_Rc23B4r&NPDH8I+U(AciU*}c22S3 zdyWDrENYgpuLg5r^m|f(p}LsUYfi7&f<(`KDz9;y)cYY#xOink#?krhebw#K_^}$b z(T(%u03@>G#KUPNE)umGve|7$OqBB+hdO(Uqn7DM)Ou{UDSk~{XY+pV&!o2k)J{Qn zdRu}NbNAA6xKNRH9U&^6;~h89Z`&|@PHBm8fQju4n!X`bHO5kaf{g*W<|kj^i&%Mj zBa>gv(8t?ukrXIJVMH+e?S>!e-%50K1Mkdf0B9%?#D9;{qk=Y#2;qaN;s06}-)HPb z?;Uuo0WCLErJ-lulj73r>5a=I95B+KOU-c=NDWm&`X+6iB~wQBJJZ~8lxrTJwJ+s} z?0QH;0Wl!ndjC|iGhnHoRlf20W;K6kgqu9{W@noE@^zcro{UA&GuUadAssR0j`Fr7 zytZk0kZ_6Wguc4Su5%tf!<&%m&rwoPJx`&9JD;*wYK$G$&w08M=+juP>it_qd@_Y2 zE200V{S;oO1`a>FNe)_{O)loAg-pO8OC^&Z2t|^;+hz=_g=B~uBnkynJy_sDk^`x> zEM)DnNW-LsIt?0ulT-mvOiL`7MWuc#I^FK!`NtQYXCVA-qXH3NOkm3KhU84&1oHW1n{6SuEw)4hU~{`opVOUp|C zIGhC)EU@X}=7nE1Cx5~(f}H7loS^`uRFjDI8DI(vY(-_3DoF#8TAWI;k*LLhgJ2>; zidbX6U<7oE(n5Mk>7c=8#zmGOgUk-8>Z;6%jhaKL`R#V>dsTHkb6R|6Cl}J85-l%L zLtt%33qODvX5K;!6_kdC=G#LG;0sPjYWR){j5mRNmiePkV7J%S^EBEbMdt3ERj6mfD2MXNcN1SkzByNh>X`&*rHxV zGC%Py)pk&?0-u1RnU+p|{2eNkrsJo5xAZzPF{$N@S9`Y?XTtAiyQU5LDNq*Ts?}}I ze*M(quh~6{MhcikT>14i!PRQVn{P^z)3>*`8Qlpz@8A>JD)HfJH+o3`+Kx(o;vFhc zlS0Mt+B$CqF`#N^QL_*7`ZzG6Rr!uXMNyht18h?*p6Y)JBUpFt zRi2#&_Ou13q?R}BJT=)cxbE$Yf{;oE^va|_-u-kW&9qo>DJ}s62x6S9TBTH)%}q$i zt1F<%a(y>Q3W6YCix6 zL@Axjo(b%oIGTGuf@48T!^n#KTE{R;;6o2O+xNFN4?YWzhV9o`W2CyNC(B@c_b2k7 z9TRAZLZv^sa>w<6q5QUNo?ZG~WTmHJ;_Ssc`9x=c;K#hFAW+$6P22mhih_b`qnu_G zpD=rh<=)KQjdIAYNI$Ng8tjGN&(^t_2!Uz5hBfE%60W!zw)hzYV9!mVjLJbZ!wrzj zioUo@r~!%gNs2l~#k0rh4R>CMzU6aprTC7Hni#bSxGe9S{Zs#P6=Cj(>rsF~ zKb=*yC~c;2hUH}cfL^zK1=n~bF_S`3u9xoD{R~H3bSX?IWB?qIXjmaBy_i&$(Cvo< zY>%7*NJIk0uU{x_O?t0(n)Bbo#+*ena5*6n^_z!1umv#`h(TQm;yTr!&3mQVjMbCb z#HG{N)R0oSyeu|yE**OyeO(vRyos_qzVgZCSqM`7_Uxg@*c98dUfe$&9v-5@BZ8DN z_g)79UD^#H;cMy;C`Jn(N@^M=`(9gb^Xs(&5{5xV z)$km9?G#6I7tc3~wj$Xddxh43??2%~mC~_q435xM;r|V(L;yDk(B1jQI7W zDSpEkGa(B<`7 zj@7Dn)7%OSd_p#g(%;Tuck1sCp?`K7AIoOS;JPqGrqrmW)5tN3X61_c3%2TKoW&QR zqNAgG0Qky7PoF=pJdKEms64;%j%X%|jCZie@>?8pPtixtXTNJx@L*>BQTfN-Z~X50 zZ_Li)cg@V`dRllFTm}E}$*-KU2ZD{OVAv|K|JHov!>F35>2JLJ8-GA}v|wPml-u$e zv_Y44T2BD8Gz8`N=r|qN*57#bKlE~Tz{hXqfmr<+9sk6>{y$Dd$HDuVO91>J!ZI=_ zS^x2V5Q`v{0Y*STkMPC-y)~cbi(`I!fO*6Mr|w|vKt{otVMFm<(>J_C&sFqdJ{P`65NM)`N=!Of>a|1W_+VsDq18itEYoy4Y_ z2t1Fa6ck{l==_6LDdzvM%@9Ed@l6~suK*396oCBc72iDCO-doEsp!WdA1UX zSh0Nu?0*Ldh!@GH0Tp&P?l*0|BMd2ih%wNoA))toS@8R^nl-^W=3?1buJv!3fd{RJ zkX$VPC$j{^{~ zLK+QtSs4HQT>$Df>~HsoG|S!ux63!P0{Y*ta>e+X_fli=n%5Wal^2EF!Ma!G=bzPV zt|8l2q9*f;(ZiR&AzK0z7dLQe`1PdaBEFfpa1IO>-=S38=^|Phe!D8=XUhd z<-h)gj}EFCWVSzU#dvEyt$by)36Em8Z6fSk))j(}CK;;wO!E7wt<)vIdWI&{>L$)j zh>kTj%db=Q=L0#$Mz;P&nE``HTnR9fi?bfOA?p?DL;cn~UrGC_mTNkp4w_s$=m0?y z@)LSe|1j_70!%Xq5)diGF%G()JB-<{QkLAUsA@@Y-J~b^npFmnY9@}?Gc?M49mXO^ z&AU+(!Kc|pWdr|i3OGX!Dv)8wxVX4VIjwZA2ghsfB_6Ew@~dpG-a03MDdKI8*SdnQ zi6Cw3+de_nbG4ze87tO6N_fYKpR3xzpB z{VypK3;f-)59;SgpWCR};zCOP#JC}WKnFGNpkN43e6?!`-x;q`&&1P#s1ON_4lMws|l@fd+G zU%hRnL(85$HE=uMtT|jx%xQePe;c*E-SJcD#Drltm#to3Q+3*|hWC>n28BB8=sh#1 z#8`1xTNbbOJRpNnCi7djWu&LJxyY$_AWL|-$pW5knW>WZ)N_Te?yXoYb+;_JZM$&( zyGkY^h(x4u)>VKQeD?{q!T5cN7twn4`z1x4{emyft^Tva0^Y2s9 zcso)HjMwAid{$S_3-r^l> zGvkQl@7;9M{^7X6c`3!pC5^P%N8JFSeeoC<^W}!o9~ZdiwMT)gobysfY4D{g=SyPT z0cKbaJVWGl3*`-+|7@M{X+r%N>FC$6%9cL_hovrl2`tI_Opi-_P$cAiNgAu^Cb-` z1<4@!MQzo`QQj^WuWmhA&B|N0UZtN}RnWf}qCXd(SsgyU&4_b5!>VIeGb=0`-LWZ? zr2R&OxY`T7!ZR1X+DdCbe-gn{SqoU8&{zh~-{B9~A_PQVznDW4Q z)5fDF-dp8-UQ>-*J7afa`dp8zdSfzbW~yJ3|&VuxXw%OgWx#f5lP$n6d3g6A9zvr8oUGrnq=yA$)a}Evj`m z22)KpJs?nM!Y;J54M!;AWY_{y)SUJ?PWDt zjq(1u8FuKk)mzA+G?IPIb6M(Y7jr9SLzMy=_pN=bXUGl&si_(g$B{0$T=$GJ>^*e; zrduIlDmy|rk!%Hx2p_z!#oNa-Y?y~9dtI+P%2_yldqbhX1X}G;h12@3A;g^4JyUh% zJHN>62PqWXp>kaLjJuB}gt=f-Z!u#j*29bVjto~9dUkeR+Ymq3jJIIa-;y>;>-;!x zF8Z*e32qI)bw3wHif`@VmU^X?2g$O);0#+p^P$|j;o7&%#4N@vvj?^~zKpht=uEl}v?jin;+54GqekAk+1w=>>2cTvf<@GSeUT@>&PVyKKX$ zQ%+hY?ug7zzWi1azW9OmLIf(?$cXOjXjz25D-oH|e5iUw_(WnVGCRj|M`N8~h==6c z_QfT}lRl=d`*7I){p6h3p?*^*-f7XD8SRhzLY=T(z_x@foUakYG z+w@huTkF{tWe3698D(NgD?P40@$@@df#c^Gc*{*;b?()ovhN5-omZLgh%SpJ1DY4S zwE~AIJ$+3X+o@UTMxT-MSfI}5qaT82uVp99!_(OWrzuRnvbuDm+)6opBLVerU&V-U zY55V@3@Xof-4G}|3q~yH<)N=O%0`|f+%&=cMoLObWoynL_}@<5oP;TfysbOp9VGSy zJgXkE#9Lm*(ZEBp&vEf2#KssD$b;r!GqoFuw8PhDV7wU9fO=dWIuqY> z{LrB@?qaiacFb``$1vl}tmF0_pFg3Vf{SwXMS7Y>uH|UM6+77XV)99M4h`m=7RED8>fnY$fZ+5+RdhWScBCmM~J8PDEKEG9Aj2eLaNw-oA4>{J!5g?_clz z{&Tr8c zL7usViFPgUqi`*B4?-kT=3&&=&5C%{YCwe ziGBNqzv34Y*7K)fu4OUoJFR*plgI8Q%|Adae-2h25eP6QtmF%x3JTxQ87n6~>!S$c zG>$-3_vg5_vn!x5q4|qaxVPViM;3^BH?D_|<{$iJ3dlw0Q)I9AKm7K9(I2!-eKo<| z3i1T8uoMbmq-)lwNF>SkEoN7AgOt??$$EIl-m_OXyBVEfm45eQ2*JU%B@&sE12Tt* z4CrKM8FHQ#A^6yFdkW1*fI}0{kVw>_AqO`PkGpOCMqjy=)e|lCu?xj^)p7vzA~l8v zo)o9)-pfIBDHx!zw2n0Kk0+o2l70n1k6KIZ^lj8jq_+dmBmQnR7F;Z34p=#S& zyhFav_L@%U1qAd+hk>Ru=x)J;N&LBigU1svg63#(jaWi&_=o`&0_tvjRw#=_+jU9kv9s_Pgo_-39G3!66$-hwRZTfJnjB3=y`8H_ewz526@~|&$AUd8Rbi2elgFkteuOh1 zQN{=ISKEsO13gxsj?FZvd^&lb)1f!B`^o`kf)K2hN8RLd>&jaV;|mvx&ERid^XMqi zYRIPz3EtXBkiuaErz#r>8n7Xe=uNJkq>%Rpx3BFC01ZgMZ}o}hfN)IgXj{tY67w>! z=8OKCmKpmvD!;8VBT%r+5uWt}}Lp6jghuZ26 zC8?dgB{cl0BLZl2c?w|c$%3CedD5fHs=-|ZN`61z76<7}X!1pmAAv=xy+=#@sMmc@ zf&6YmC)%;=dHMNF{;#M#2z^>w+TGO`MKiCu&*v?<2h^V=5O@F{aRv{KNR8teU^HuX zM*%BTRw~a{HZsyboH?)q6w;`>!9`*;jMSdZmnpwqPT*fFJ>Vz&neW=;mYW)q-yd46 zr_K#c%i^7l1#?rQU67z^M5|CUkr%9~s+yYogLd<0a)vc#V|YX7nGqXP>}Hv)P&#vI zqXQ$UiNuZP91W^KfzKFb1%i!qr+Vl&Vh9EXQKxZ3fB&t&-_Q%7S-f9=(^~uEdEdUZ zFf<4yo2?ho)QF%J@LH08_CVa216aCAfb^72kB&#fc1j2g3@L^{76lJGoCC;l-x;^^ zhd8+koJ167!E-;z5_&|M7Z3i(0IH*L2??%NR1w^E!~v-WP*}LmFC#B6t*l($U-D$^ zbF0K9fF|CK@4jZ1pIa*EbqQxFYGh<|=UnSm3`940Da3TAcXA39O4SKlbq2bYdYX~P z)9);@BsK-}Tnq>zt9gL*$iBlKXtkMuhmZE0=yEZbuBxi)QRBFH_`2s*ag`stq8E{S zvvtjith8?K9eltrw{|;!l0AGQ+{k(rXsD=$b~+ z{H`!Q25w#s;{Co@LnJq;*3XNj;nVNP>Q46QPm@-vs*-o6m^R~;!oaJU%Rfv-C+p#O zijO^J>III6hgaUzP~WPuQF3_ftERwA{fTk9<2%~Tsj=ldcvxoIDtHI z8Mqe1X)zP;HX8)vWer@D!8>2T(5H^L+Fw2$fw1H={WUxXA6DL*_#QOafFawNNr@GuHX4`%_C`p zi+3u9L>?wN4WJ*e3Y}6jbU*Z0`Sp_zD(vUT8Q{h% zBPnw?W;4B8Z{zI#(H-D@7l^XLbIT%CKLltR#aa^cSDBN8d=xt?PuH8`zVgpj7f@)S zrKejRhz@A1GvW(4L0y_@1_pnlV{|1P3D%0>Ds!6)TbfuJ`0i(G?1jkce~OmBf~WLN zrCM8$ELJjyGTSL5)XvvZgHRFJbl0y`;AtPNVXH7r?+IN;sO-j|kBv|3j#<%PVdL^# z2+2UGw-_yPC^Hl9F{k)=LWcN1dZ0i> zwq5u2L%)!g9G+PV9qxns Date: Thu, 1 Jun 2023 12:14:01 +0300 Subject: [PATCH 104/207] add tests on make device public/private --- .../msa/ui/pages/DevicePageElements.java | 30 +++++ .../server/msa/ui/pages/DevicePageHelper.java | 20 +++ .../devicessmoke/AssignToCustomerTest.java | 3 +- .../devicessmoke/MakeDevicePrivateTest.java | 79 +++++++++++ .../devicessmoke/MakeDevicePublicTest.java | 127 ++++++++++++++++++ .../server/msa/ui/utils/Const.java | 1 + 6 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java create mode 100644 msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePublicTest.java diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DevicePageElements.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DevicePageElements.java index e400a67567..f6c901c76c 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DevicePageElements.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DevicePageElements.java @@ -60,6 +60,12 @@ public class DevicePageElements extends OtherPageElementsHelper { private static final String DEVICE_STATE_SELECT = "//div[contains(@class,'tb-filter-panel')]//mat-select[@role='combobox']"; private static final String LIST_OF_DEVICES_STATE = "//div[@class='status']"; private static final String LIST_OF_DEVICES_PROFILE = "//mat-cell[contains(@class,'deviceProfileName')]"; + private static final String MAKE_DEVICE_PUBLIC_BTN = DEVICE + "/ancestor::mat-row//mat-icon[contains(text(),'share')]/parent::button"; + private static final String DEVICE_IS_PUBLIC_CHECKBOX = DEVICE + "/ancestor::mat-row//mat-icon[contains(text(),'check_box')]"; + private static final String MAKE_DEVICE_PUBLIC_BTN_DETAILS_TAB = "//span[contains(text(),'Make device public')]/parent::button"; + private static final String MAKE_DEVICE_PRIVATE_BTN = DEVICE + "/ancestor::mat-row//mat-icon[contains(text(),'reply')]/parent::button"; + private static final String DEVICE_IS_PRIVATE_CHECKBOX = DEVICE + "/ancestor::mat-row//mat-icon[contains(text(),'check_box_outline_blank')]"; + private static final String MAKE_DEVICE_PRIVATE_BTN_DETAILS_TAB = "//span[contains(text(),'Make device private')]/parent::button"; public WebElement device(String deviceName) { return waitUntilElementToBeClickable(String.format(DEVICE, deviceName)); @@ -204,4 +210,28 @@ public class DevicePageElements extends OtherPageElementsHelper { public List listOfDevicesProfile() { return waitUntilVisibilityOfElementsLocated(LIST_OF_DEVICES_PROFILE); } + + public WebElement makeDevicePublicBtn(String deviceName) { + return waitUntilElementToBeClickable(String.format(MAKE_DEVICE_PUBLIC_BTN, deviceName)); + } + + public WebElement deviceIsPublicCheckbox(String deviceName) { + return waitUntilVisibilityOfElementLocated(String.format(DEVICE_IS_PUBLIC_CHECKBOX, deviceName)); + } + + public WebElement makeDevicePublicBtnDetailsTab() { + return waitUntilElementToBeClickable(MAKE_DEVICE_PUBLIC_BTN_DETAILS_TAB); + } + + public WebElement makeDevicePrivateBtn(String deviceName) { + return waitUntilElementToBeClickable(String.format(MAKE_DEVICE_PRIVATE_BTN, deviceName)); + } + + public WebElement deviceIsPrivateCheckbox(String deviceName) { + return waitUntilVisibilityOfElementLocated(String.format(DEVICE_IS_PRIVATE_CHECKBOX, deviceName)); + } + + public WebElement makeDevicePrivateBtnDetailsTab() { + return waitUntilElementToBeClickable(MAKE_DEVICE_PRIVATE_BTN_DETAILS_TAB); + } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DevicePageHelper.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DevicePageHelper.java index 80f4ff49b3..599b9f104f 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DevicePageHelper.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/pages/DevicePageHelper.java @@ -123,4 +123,24 @@ public class DevicePageHelper extends DevicePageElements { sleep(2); //wait until the action is counted submitBtn().click(); } + + public void makeDevicePublicByRightSideBtn(String deviceName) { + makeDevicePublicBtn(deviceName).click(); + warningPopUpYesBtn().click(); + } + + public void makeDevicePublicFromDetailsTab() { + makeDevicePublicBtnDetailsTab().click(); + warningPopUpYesBtn().click(); + } + + public void makeDevicePrivateByRightSideBtn(String deviceName) { + makeDevicePrivateBtn(deviceName).click(); + warningPopUpYesBtn().click(); + } + + public void makeDevicePrivateFromDetailsTab() { + makeDevicePrivateBtnDetailsTab().click(); + warningPopUpYesBtn().click(); + } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/AssignToCustomerTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/AssignToCustomerTest.java index 8c0a45aa03..c4246e6df5 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/AssignToCustomerTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/AssignToCustomerTest.java @@ -34,6 +34,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.thingsboard.server.msa.ui.base.AbstractBasePage.random; import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME; +import static org.thingsboard.server.msa.ui.utils.Const.PUBLIC_CUSTOMER_NAME; @Feature("Assign to customer") public class AssignToCustomerTest extends AbstractDeviceTest { @@ -58,7 +59,7 @@ public class AssignToCustomerTest extends AbstractDeviceTest { @AfterClass public void deleteCustomer() { deleteCustomerById(customerId); - deleteCustomerByName("Public"); + deleteCustomerByName(PUBLIC_CUSTOMER_NAME); deleteDeviceByName(device1.getName()); } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java new file mode 100644 index 0000000000..3d9ec2b278 --- /dev/null +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java @@ -0,0 +1,79 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.msa.ui.tests.devicessmoke; + +import io.qameta.allure.Description; +import io.qameta.allure.Epic; +import org.openqa.selenium.WebElement; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.msa.ui.pages.CustomerPageHelper; +import org.thingsboard.server.msa.ui.utils.EntityPrototypes; + +import static org.thingsboard.server.msa.ui.base.AbstractBasePage.random; +import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME; +import static org.thingsboard.server.msa.ui.utils.Const.PUBLIC_CUSTOMER_NAME; + +@Epic("Make device private") +public class MakeDevicePrivateTest extends AbstractDeviceTest { + + private CustomerPageHelper customerPage; + + @BeforeMethod + public void createPublicDevice() { + customerPage = new CustomerPageHelper(driver); + Device device = testRestClient.postDevice("", EntityPrototypes.defaultDevicePrototype(ENTITY_NAME + random())); + testRestClient.setDevicePublic(device.getId()); + deviceName = device.getName(); + } + + @AfterClass + public void deletePublicCustomer() { + deleteCustomerByName(PUBLIC_CUSTOMER_NAME); + } + + @Test(groups = "smoke") + @Description("Make device private by right side btn") + public void makeDevicePrivateByRightSideBtn() { + sideBarMenuView.goToDevicesPage(); + devicePage.makeDevicePrivateByRightSideBtn(deviceName); + WebElement customerInColumn = devicePage.deviceCustomerOnPage(deviceName); + assertIsDisplayed(devicePage.deviceIsPrivateCheckbox(deviceName)); + assertInvisibilityOfElement(customerInColumn); + + sideBarMenuView.customerBtn().click(); + customerPage.manageCustomersDevicesBtn(PUBLIC_CUSTOMER_NAME).click(); + devicePage.assertEntityIsNotPresent(deviceName); + } + + @Test(groups = "smoke") + @Description("Make device public by btn on details tab") + public void makeDevicePrivateFromDetailsTab() { + sideBarMenuView.goToDevicesPage(); + devicePage.device(deviceName).click(); + WebElement customerInColumn = devicePage.deviceCustomerOnPage(deviceName); + devicePage.makeDevicePrivateFromDetailsTab(); + devicePage.closeDeviceDetailsViewBtn().click(); + assertIsDisplayed(devicePage.deviceIsPrivateCheckbox(deviceName)); + assertInvisibilityOfElement(customerInColumn); + + sideBarMenuView.customerBtn().click(); + customerPage.manageCustomersDevicesBtn(PUBLIC_CUSTOMER_NAME).click(); + devicePage.assertEntityIsNotPresent(deviceName); + } +} diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePublicTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePublicTest.java new file mode 100644 index 0000000000..ad5b379437 --- /dev/null +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePublicTest.java @@ -0,0 +1,127 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.msa.ui.tests.devicessmoke; + +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.thingsboard.server.msa.ui.pages.CustomerPageHelper; +import org.thingsboard.server.msa.ui.tabs.AssignDeviceTabHelper; +import org.thingsboard.server.msa.ui.utils.EntityPrototypes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.thingsboard.server.msa.ui.base.AbstractBasePage.random; +import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME; +import static org.thingsboard.server.msa.ui.utils.Const.PUBLIC_CUSTOMER_NAME; + +@Feature("Make device public") +public class MakeDevicePublicTest extends AbstractDeviceTest { + + private CustomerPageHelper customerPage; + private AssignDeviceTabHelper assignDeviceTab; + private String deviceName1; + + @BeforeClass + public void createFirstDevice() { + customerPage = new CustomerPageHelper(driver); + assignDeviceTab = new AssignDeviceTabHelper(driver); + + deviceName1 = testRestClient.postDevice("", EntityPrototypes.defaultDevicePrototype(ENTITY_NAME + random())).getName(); + } + + @AfterClass + public void cleanUp() { + deleteCustomerByName(PUBLIC_CUSTOMER_NAME); + deleteDeviceByName(deviceName1); + } + + @BeforeMethod + public void createSecondDevice() { + deviceName = testRestClient.postDevice("", EntityPrototypes.defaultDevicePrototype(ENTITY_NAME + random())).getName(); + } + + @Test(groups = "smoke", priority = 10) + @Description("Make device public by right side btn") + public void makeDevicePublicByRightSideBtn() { + sideBarMenuView.goToDevicesPage(); + devicePage.makeDevicePublicByRightSideBtn(deviceName); + + assertIsDisplayed(devicePage.deviceIsPublicCheckbox(deviceName)); + assertIsDisplayed(devicePage.deviceCustomerOnPage(deviceName)); + assertThat(devicePage.deviceCustomerOnPage(deviceName).getText()) + .as("Customer in customer column is Public customer") + .isEqualTo(PUBLIC_CUSTOMER_NAME); + + sideBarMenuView.customerBtn().click(); + customerPage.manageCustomersDevicesBtn(PUBLIC_CUSTOMER_NAME).click(); + assertIsDisplayed(devicePage.device(deviceName)); + } + + @Test(groups = "smoke", priority = 10) + @Description("Make device public by btn on details tab") + public void makeDevicePublicFromDetailsTab() { + sideBarMenuView.goToDevicesPage(); + devicePage.device(deviceName).click(); + devicePage.makeDevicePublicFromDetailsTab(); + devicePage.closeDeviceDetailsViewBtn().click(); + + assertIsDisplayed(devicePage.deviceIsPublicCheckbox(deviceName)); + assertIsDisplayed(devicePage.deviceCustomerOnPage(deviceName)); + assertThat(devicePage.deviceCustomerOnPage(deviceName).getText()) + .as("Customer in customer column is Public customer") + .isEqualTo(PUBLIC_CUSTOMER_NAME); + + sideBarMenuView.customerBtn().click(); + customerPage.manageCustomersDevicesBtn(PUBLIC_CUSTOMER_NAME).click(); + assertIsDisplayed(devicePage.device(deviceName)); + } + + @Test(groups = "smoke", priority = 20) + @Description("Make device public by assign to public customer") + public void makeDevicePublicByAssignToPublicCustomer() { + sideBarMenuView.goToDevicesPage(); + devicePage.assignBtn(deviceName).click(); + assignDeviceTab.assignOnCustomer(PUBLIC_CUSTOMER_NAME); + assertIsDisplayed(devicePage.deviceIsPublicCheckbox(deviceName)); + assertIsDisplayed(devicePage.deviceCustomerOnPage(deviceName)); + assertThat(devicePage.deviceCustomerOnPage(deviceName).getText()).isEqualTo(PUBLIC_CUSTOMER_NAME); + + sideBarMenuView.customerBtn().click(); + customerPage.manageCustomersDevicesBtn(PUBLIC_CUSTOMER_NAME).click(); + assertIsDisplayed(devicePage.device(deviceName)); + } + + @Test(groups = "smoke", priority = 20) + @Description("Make several devices public by assign to public customer") + public void makePublicSeveralDevicesByAssignOnPublicCustomer() { + sideBarMenuView.goToDevicesPage(); + devicePage.assignSelectedDevices(deviceName, deviceName1); + assignDeviceTab.assignOnCustomer(PUBLIC_CUSTOMER_NAME); + assertIsDisplayed(devicePage.deviceIsPublicCheckbox(deviceName)); + assertIsDisplayed(devicePage.deviceCustomerOnPage(deviceName)); + assertThat(devicePage.deviceCustomerOnPage(deviceName).getText()) + .as("Customer in customer column is Public customer") + .isEqualTo(PUBLIC_CUSTOMER_NAME); + + sideBarMenuView.customerBtn().click(); + customerPage.manageCustomersDevicesBtn(PUBLIC_CUSTOMER_NAME).click(); + assertIsDisplayed(devicePage.device(deviceName)); + assertIsDisplayed(devicePage.device(deviceName1)); + } +} diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/Const.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/Const.java index 0b9e173e6d..892b4af9bc 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/Const.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/utils/Const.java @@ -47,4 +47,5 @@ public class Const { public static final String DEVICE_PROFILE_IS_REQUIRED_MESSAGE = "Device profile is required"; public static final String DEVICE_ACTIVE_STATE = "Active"; public static final String DEVICE_INACTIVE_STATE = "Inactive"; + public static final String PUBLIC_CUSTOMER_NAME = "Public"; } From d1b22a077c1bf2f6a3b43fec0e0c5f4462154a7e Mon Sep 17 00:00:00 2001 From: kalytka Date: Thu, 1 Jun 2023 12:27:03 +0300 Subject: [PATCH 105/207] new rulenode-core-config --- .../resources/public/static/rulenode/rulenode-core-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js index 1fbee23f7f..69953bd64f 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js +++ b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js @@ -1 +1 @@ -System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/platform-browser","@angular/material/select","@angular/material/core","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/icon","@angular/material/chips","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/material/tooltip","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","rxjs","@angular/material/expansion","@home/components/public-api","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@angular/material/radio","@angular/material/slide-toggle","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component"],(function(e){"use strict";var t,r,n,a,o,i,l,s,m,u,p,d,c,f,g,y,x,b,h,C,F,v,L,k,I,T,N,q,S,M,A,G,E,D,V,P,R,w,O,H,K,B,U,z,j,_,$,J,Q,Y,W,X,Z,ee,te,re,ne,ae,oe,ie,le,se,me,ue,pe,de,ce,fe,ge,ye,xe,be,he,Ce,Fe,ve,Le,ke,Ie,Te,Ne,qe,Se,Me,Ae,Ge,Ee,De,Ve,Pe,Re,we,Oe,He,Ke;return{setters:[function(e){t=e,r=e.Component,n=e.Pipe,a=e.ViewChild,o=e.forwardRef,i=e.Input,l=e.NgModule},function(e){s=e.RuleNodeConfigurationComponent,m=e.AttributeScope,u=e.telemetryTypeTranslations,p=e.ServiceType,d=e.ScriptLanguage,c=e.AlarmSeverity,f=e.alarmSeverityTranslations,g=e.EntitySearchDirection,y=e.entitySearchDirectionTranslations,x=e.EntityType,b=e.PageComponent,h=e.MessageType,C=e.messageTypeNames,F=e,v=e.SharedModule,L=e.AggregationType,k=e.aggregationTranslations,I=e.NotificationType,T=e.SlackChanelType,N=e.SlackChanelTypesTranslateMap,q=e.alarmStatusTranslations,S=e.AlarmStatus},function(e){M=e},function(e){A=e,G=e.Validators,E=e.NgControl,D=e.NG_VALUE_ACCESSOR,V=e.NG_VALIDATORS,P=e.UntypedFormControl},function(e){R=e,w=e.CommonModule},function(e){O=e},function(e){H=e},function(e){K=e},function(e){B=e},function(e){U=e},function(e){z=e},function(e){j=e},function(e){_=e},function(e){$=e},function(e){J=e.getCurrentAuthState,Q=e,Y=e.isDefinedAndNotNull,W=e.isObject,X=e.isUndefinedOrNull,Z=e.isNotEmptyStr},function(e){ee=e},function(e){te=e},function(e){re=e},function(e){ne=e.ENTER,ae=e.COMMA,oe=e.SEMICOLON},function(e){ie=e},function(e){le=e},function(e){se=e},function(e){me=e},function(e){ue=e.coerceBooleanProperty},function(e){pe=e},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e.tap,xe=e.map,be=e.mergeMap,he=e.takeUntil,Ce=e.startWith,Fe=e.share},function(e){ve=e},function(e){Le=e},function(e){ke=e.of,Ie=e.Subject},function(e){Te=e},function(e){Ne=e.HomeComponentsModule},function(e){qe=e},function(e){Se=e},function(e){Me=e},function(e){Ae=e},function(e){Ge=e},function(e){Ee=e},function(e){De=e},function(e){Ve=e},function(e){Pe=e},function(e){Re=e},function(e){we=e},function(e){Oe=e},function(e){He=e},function(e){Ke=e}],execute:function(){class Be extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",Be),Be.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Be,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Be.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Be,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"

",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Be,decorators:[{type:r,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ue{constructor(e){this.sanitizer=e}transform(e){return this.sanitizer.bypassSecurityTrustHtml(e)}}e("SafeHtmlPipe",Ue),Ue.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ue,deps:[{token:z.DomSanitizer}],target:t.ɵɵFactoryTarget.Pipe}),Ue.ɵpipe=t.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Ue,name:"safeHtml"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ue,decorators:[{type:n,args:[{name:"safeHtml"}]}],ctorParameters:function(){return[{type:z.DomSanitizer}]}});class ze extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[G.required,G.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[G.required,G.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ze),ze.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ze,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ze.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ze,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ze,decorators:[{type:r,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class je extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===m.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",je),je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:je,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:je,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:je,decorators:[{type:r,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class _e extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[G.required]]})}}e("CheckPointConfigComponent",_e),_e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_e,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_e,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_e,decorators:[{type:r,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class $e extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[G.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===d.JS?[G.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===d.TBEL?[G.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.clearAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=e===d.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",n=this.clearAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.clearAlarmConfigForm.get(t).setValue(e)}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",$e),$e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),$e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$e,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,decorators:[{type:r,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Je extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.alarmSeverities=Object.keys(c),this.alarmSeverityTranslationMap=f,this.separatorKeysCodes=[ne,ae,oe],this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,r=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([G.required]),this.createAlarmConfigForm.get("severity").setValidators([G.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let n=this.createAlarmConfigForm.get("scriptLang").value;n!==d.TBEL||this.tbelEnabled||(n=d.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(n,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const a=!1===t||!0===r;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(a&&n===d.JS?[G.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(a&&n===d.TBEL?[G.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.createAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=e===d.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",n=this.createAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.createAlarmConfigForm.get(t).setValue(e)}))}removeKey(e,t){const r=this.createAlarmConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.createAlarmConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",Je),Je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Je,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,decorators:[{type:r,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Qe extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[G.required]],entityType:[e?e.entityType:null,[G.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[G.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[G.required,G.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==x.DEVICE&&t!==x.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([G.required,G.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",Qe),Qe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qe,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,decorators:[{type:r,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ye extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[G.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[G.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[G.required,G.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,r=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([G.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&r?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",Ye),Ye.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ye.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ye,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,decorators:[{type:r,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class We extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,G.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,G.required]})}}e("DeviceProfileConfigComponent",We),We.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),We.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:We,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,decorators:[{type:r,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Xe extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[G.required,G.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[G.required,G.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(){const e=this.generatorConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",n=this.generatorConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.generatorConfigForm.get(t).setValue(e)}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}var Ze;e("GeneratorConfigComponent",Xe),Xe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xe,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,decorators:[{type:r,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(Ze||(Ze={}));const et=new Map([[Ze.CUSTOMER,"tb.rulenode.originator-customer"],[Ze.TENANT,"tb.rulenode.originator-tenant"],[Ze.RELATED,"tb.rulenode.originator-related"],[Ze.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[Ze.ENTITY,"tb.rulenode.originator-entity"]]);var tt;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(tt||(tt={}));const rt=new Map([[tt.CIRCLE,"tb.rulenode.perimeter-circle"],[tt.POLYGON,"tb.rulenode.perimeter-polygon"]]);var nt;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(nt||(nt={}));const at=new Map([[nt.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[nt.SECONDS,"tb.rulenode.time-unit-seconds"],[nt.MINUTES,"tb.rulenode.time-unit-minutes"],[nt.HOURS,"tb.rulenode.time-unit-hours"],[nt.DAYS,"tb.rulenode.time-unit-days"]]);var ot;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(ot||(ot={}));const it=new Map([[ot.METER,"tb.rulenode.range-unit-meter"],[ot.KILOMETER,"tb.rulenode.range-unit-kilometer"],[ot.FOOT,"tb.rulenode.range-unit-foot"],[ot.MILE,"tb.rulenode.range-unit-mile"],[ot.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var lt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(lt||(lt={}));const st=new Map([[lt.ID,"tb.rulenode.entity-details-id"],[lt.TITLE,"tb.rulenode.entity-details-title"],[lt.COUNTRY,"tb.rulenode.entity-details-country"],[lt.STATE,"tb.rulenode.entity-details-state"],[lt.CITY,"tb.rulenode.entity-details-city"],[lt.ZIP,"tb.rulenode.entity-details-zip"],[lt.ADDRESS,"tb.rulenode.entity-details-address"],[lt.ADDRESS2,"tb.rulenode.entity-details-address2"],[lt.PHONE,"tb.rulenode.entity-details-phone"],[lt.EMAIL,"tb.rulenode.entity-details-email"],[lt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var mt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(mt||(mt={}));const ut=new Map([[mt.FIRST,"tb.rulenode.first-message"],[mt.LAST,"tb.rulenode.last-message"],[mt.ALL,"tb.rulenode.all-messages"]]);var pt,dt;!function(e){e.ASC="ASC",e.DESC="DESC"}(pt||(pt={})),function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(dt||(dt={}));const ct=new Map([[dt.STANDARD,"tb.rulenode.sqs-queue-standard"],[dt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),ft=["anonymous","basic","cert.PEM"],gt=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),yt=["sas","cert.PEM"],xt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var bt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(bt||(bt={}));const ht=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Ct=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Ft;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Ft||(Ft={}));const vt=new Map([[Ft.CUSTOM,{value:Ft.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Ft.ADD,{value:Ft.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Ft.SUB,{value:Ft.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Ft.MULT,{value:Ft.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Ft.DIV,{value:Ft.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Ft.SIN,{value:Ft.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Ft.SINH,{value:Ft.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Ft.COS,{value:Ft.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Ft.COSH,{value:Ft.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Ft.TAN,{value:Ft.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Ft.TANH,{value:Ft.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Ft.ACOS,{value:Ft.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Ft.ASIN,{value:Ft.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Ft.ATAN,{value:Ft.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Ft.ATAN2,{value:Ft.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Ft.EXP,{value:Ft.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Ft.EXPM1,{value:Ft.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Ft.SQRT,{value:Ft.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Ft.CBRT,{value:Ft.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Ft.GET_EXP,{value:Ft.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Ft.HYPOT,{value:Ft.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Ft.LOG,{value:Ft.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Ft.LOG10,{value:Ft.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Ft.LOG1P,{value:Ft.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Ft.CEIL,{value:Ft.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Ft.FLOOR,{value:Ft.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Ft.FLOOR_DIV,{value:Ft.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Ft.FLOOR_MOD,{value:Ft.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Ft.ABS,{value:Ft.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Ft.MIN,{value:Ft.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Ft.MAX,{value:Ft.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Ft.POW,{value:Ft.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Ft.SIGNUM,{value:Ft.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Ft.RAD,{value:Ft.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Ft.DEG,{value:Ft.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Lt,kt;!function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Lt||(Lt={})),function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(kt||(kt={}));const It=new Map([[Lt.ATTRIBUTE,"tb.rulenode.attribute-type"],[Lt.TIME_SERIES,"tb.rulenode.time-series-type"],[Lt.CONSTANT,"tb.rulenode.constant-type"],[Lt.MESSAGE_BODY,"tb.rulenode.message-body-type"],[Lt.MESSAGE_METADATA,"tb.rulenode.message-metadata-type"]]),Tt=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var Nt,qt;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(Nt||(Nt={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(qt||(qt={}));const St=new Map([[Nt.SHARED_SCOPE,"tb.rulenode.shared-scope"],[Nt.SERVER_SCOPE,"tb.rulenode.server-scope"],[Nt.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class Mt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=tt,this.perimeterTypes=Object.keys(tt),this.perimeterTypeTranslationMap=rt,this.rangeUnits=Object.keys(ot),this.rangeUnitTranslationMap=it,this.timeUnits=Object.keys(nt),this.timeUnitsTranslationMap=at}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[G.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[G.required]],perimeterType:[e?e.perimeterType:null,[G.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[G.required,G.min(1),G.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[G.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[G.required,G.min(1),G.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[G.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,r=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([G.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||r!==tt.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([G.required,G.min(-90),G.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([G.required,G.min(-180),G.max(180)]),this.geoActionConfigForm.get("range").setValidators([G.required,G.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([G.required])),t||r!==tt.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([G.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",Mt),Mt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Mt,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mt,decorators:[{type:r,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class At extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.logConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",n=this.logConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.logConfigForm.get(t).setValue(e)}))}onValidate(){this.logConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",At),At.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:At,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),At.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:At,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:At,decorators:[{type:r,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Gt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[G.required,G.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[G.required]]})}}e("MsgCountConfigComponent",Gt),Gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Gt,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gt,decorators:[{type:r,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Et extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[G.required,G.min(1),G.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([G.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([G.required,G.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",Et),Et.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Et,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Et.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Et,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Et,decorators:[{type:r,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Dt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]]})}}e("PushToCloudConfigComponent",Dt),Dt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Dt,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dt,decorators:[{type:r,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Vt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]]})}}e("PushToEdgeConfigComponent",Vt),Vt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Vt,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vt,decorators:[{type:r,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Pt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",Pt),Pt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Pt,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pt,decorators:[{type:r,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Rt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[G.required,G.min(0)]]})}}e("RpcRequestConfigComponent",Rt),Rt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Rt,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rt,decorators:[{type:r,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class wt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(E),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const r of Object.keys(e))Object.prototype.hasOwnProperty.call(e,r)&&t.push(this.fb.group({key:[r,[G.required]],value:[e[r],[G.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[G.required]],value:["",[G.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",wt),wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wt,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:wt,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:D,useExisting:o((()=>wt)),multi:!0},{provide:V,useExisting:o((()=>wt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#0000008a;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:de.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ce.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wt,decorators:[{type:r,args:[{selector:"tb-kv-map-config",providers:[{provide:D,useExisting:o((()=>wt)),multi:!0},{provide:V,useExisting:o((()=>wt)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#0000008a;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class Ot extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[G.required,G.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[G.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",Ot),Ot.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ot,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ot.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ot,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ot,decorators:[{type:r,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ht extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[G.required,G.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Ht),Ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ht,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,decorators:[{type:r,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Kt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[G.required,G.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[G.required,G.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Kt),Kt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kt,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,decorators:[{type:r,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Bt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]],keys:[e?e.keys:null,[G.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",Bt),Bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Bt,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,decorators:[{type:r,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:a,args:["attributeChipList"]}]}});class Ut extends b{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup())}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=vt,this.ArgumentType=Lt,this.attributeScopeMap=St,this.argumentTypeResultMap=It,this.arguments=Object.values(Lt),this.attributeScope=Object.values(Nt),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.ngControl=this.injector.get(E),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.argumentsFormGroup=this.fb.group({}),this.argumentsFormGroup.addControl("arguments",this.fb.array([])),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray(),r=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,r),this.updateArgumentNames()}argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):this.argumentsFormGroup.enable({emitEvent:!1})}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()));const t=[];e&&e.forEach(((e,r)=>{t.push(this.createArgumentControl(e,r))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t)),this.setupArgumentsFormGroup(),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()})))}removeArgument(e){this.argumentsFormGroup.get("arguments").removeAt(e),this.updateArgumentNames()}addArgument(){const e=this.argumentsFormGroup.get("arguments"),t=this.createArgumentControl(null,e.length);e.push(t)}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Ft.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([G.minLength(this.minArgs),G.maxLength(this.maxArgs)]),this.argumentsFormGroup.get("arguments").value.length>this.maxArgs&&(this.argumentsFormGroup.get("arguments").controls.length=this.maxArgs);this.argumentsFormGroup.get("arguments").value.length{this.updateArgumentControlValidators(r),r.get("attributeScope").updateValueAndValidity({emitEvent:!0}),r.get("defaultValue").updateValueAndValidity({emitEvent:!0})}))),r}updateArgumentControlValidators(e){const t=e.get("type").value;t===Lt.ATTRIBUTE?e.get("attributeScope").enable():e.get("attributeScope").disable(),t&&t!==Lt.CONSTANT?e.get("defaultValue").enable():e.get("defaultValue").disable()}updateArgumentNames(){this.argumentsFormGroup.get("arguments").controls.forEach(((e,t)=>{e.get("name").setValue(Tt[t])}))}updateModel(){const e=this.argumentsFormGroup.get("arguments").value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Ut),Ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ut,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:D,useExisting:o((()=>Ut)),multi:!0},{provide:V,useExisting:o((()=>Ut)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"],dependencies:[{kind:"directive",type:R.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:de.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:fe.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:fe.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:ge.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:ge.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:ge.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ce.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,decorators:[{type:r,args:[{selector:"tb-arguments-map-config",providers:[{provide:D,useExisting:o((()=>Ut)),multi:!0},{provide:V,useExisting:o((()=>Ut)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class zt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.searchText="",this.dirty=!1,this.mathOperation=[...vt.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(ye((e=>{let t;t="string"==typeof e&&Ft[e]?Ft[e]:null,this.updateView(t)})),xe((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=vt.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",zt),zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zt,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:D,useExisting:o((()=>zt)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,decorators:[{type:r,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:D,useExisting:o((()=>zt)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:a,args:["operationInput",{static:!0}]}]}});class jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Ft,this.ArgumentTypeResult=kt,this.argumentTypeResultMap=It,this.attributeScopeMap=St,this.argumentsResult=Object.values(kt),this.attributeScopeResult=Object.values(qt)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[G.required]],arguments:[e?e.arguments:null,[G.required]],customFunction:[e?e.customFunction:"",[G.required]],result:this.fb.group({type:[e?e.result.type:null,[G.required]],attributeScope:[e?e.result.attributeScope:null],key:[e?e.result.key:"",[G.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,r=this.mathFunctionConfigForm.get("result").get("type").value;t===Ft.CUSTOM?this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),r===kt.ATTRIBUTE?this.mathFunctionConfigForm.get("result").get("attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result").get("attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result").get("attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",jt),jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jt,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:A.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ut,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:zt,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,decorators:[{type:r,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class _t{constructor(e,t){this.store=e,this.fb=t,this.subscriptSizing="fixed",this.searchText="",this.dirty=!1,this.messageTypes=["POST_ATTRIBUTES_REQUEST","POST_TELEMETRY_REQUEST"],this.propagateChange=e=>{},this.messageTypeFormGroup=this.fb.group({messageType:[null,[G.required,G.maxLength(255)]]})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.outputMessageTypes=this.messageTypeFormGroup.get("messageType").valueChanges.pipe(ye((e=>{this.updateView(e)})),xe((e=>e||"")),be((e=>this.fetchMessageTypes(e))))}writeValue(e){this.searchText="",this.modelValue=e,this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1}),this.dirty=!0}onFocus(){this.dirty&&(this.messageTypeFormGroup.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0}),this.dirty=!1)}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}displayMessageTypeFn(e){return e||void 0}fetchMessageTypes(e,t=!1){return this.searchText=e,ke(this.messageTypes).pipe(xe((r=>r.filter((r=>t?!!e&&r===e:!e||r.toUpperCase().startsWith(e.toUpperCase()))))))}clear(){this.messageTypeFormGroup.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}}e("OutputMessageTypeAutocompleteComponent",_t),_t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_t,selector:"tb-output-message-type-autocomplete",inputs:{autocompleteHint:"autocompleteHint",subscriptSizing:"subscriptSizing"},providers:[{provide:D,useExisting:o((()=>_t)),multi:!0}],viewQueries:[{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0,static:!0}],ngImport:t,template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,decorators:[{type:r,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:D,useExisting:o((()=>_t)),multi:!0}],template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{messageTypeInput:[{type:a,args:["messageTypeInput",{static:!0}]}],autocompleteHint:[{type:i}],subscriptSizing:[{type:i}]}});class $t extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.destroy$=new Ie,this.serviceType=p.TB_RULE_ENGINE,this.deduplicationStrategie=mt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=ut}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[Y(e?.interval)?e.interval:null,[G.required,G.min(1)]],strategy:[Y(e?.strategy)?e.strategy:null,[G.required]],outMsgType:[Y(e?.outMsgType)?e.outMsgType:null,[G.required]],queueName:[Y(e?.queueName)?e.queueName:null,[G.required]],maxPendingMsgs:[Y(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[G.required,G.min(1),G.max(1e3)]],maxRetries:[Y(e?.maxRetries)?e.maxRetries:null,[G.required,G.min(0),G.max(100)]]}),this.deduplicationConfigForm.get("strategy").valueChanges.pipe(he(this.destroy$)).subscribe((e=>{this.enableControl(e)}))}updateValidators(e){this.enableControl(this.deduplicationConfigForm.get("strategy").value)}validatorTriggers(){return["strategy"]}enableControl(e){e===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("DeduplicationConfigComponent",$t),$t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$t,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:_t,selector:"tb-output-message-type-autocomplete",inputs:["autocompleteHint","subscriptSizing"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,decorators:[{type:r,args:[{selector:"tb-action-node-msg-deduplication-config",template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Jt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[G.required]],maxLevel:[null,[]],relationType:[null],deviceTypes:[null,[G.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",Jt),Jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jt,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:D,useExisting:o((()=>Jt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-type
\n \n \n
device.device-types
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:qe.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","disabled","entityType"]},{kind:"component",type:Se.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["required","disabled","subscriptSizing"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,decorators:[{type:r,args:[{selector:"tb-device-relations-query-config",providers:[{provide:D,useExisting:o((()=>Jt)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-type
\n \n \n
device.device-types
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Qt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[G.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",Qt),Qt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qt,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:D,useExisting:o((()=>Qt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Me.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,decorators:[{type:r,args:[{selector:"tb-relations-query-config",providers:[{provide:D,useExisting:o((()=>Qt)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Yt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.truncate=r,this.fb=n,this.placeholder="tb.rulenode.message-type",this.separatorKeysCodes=[ne,ae,oe],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(h))this.messageTypesList.push({name:C.get(h[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchMessageTypes(e))),Fe())}ngAfterViewInit(){}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return!!(e&&null!=e&&e.length>0)}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return ke(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t=null;const r=e.trim(),n=this.messageTypesList.find((e=>e.name===r));t=n?{name:n.name,value:n.value}:{name:r,value:r},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Yt),Yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,deps:[{token:M.Store},{token:U.TranslateService},{token:F.TruncatePipe},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yt,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:D,useExisting:o((()=>Yt)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n \n \n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,decorators:[{type:r,args:[{selector:"tb-message-types-config",providers:[{provide:D,useExisting:o((()=>Yt)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) | async }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:F.TruncatePipe},{type:A.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:a,args:["chipList",{static:!1}]}],matAutocomplete:[{type:a,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:a,args:["messageTypeInput",{static:!1}]}]}});class Wt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=ft,this.credentialsTypeTranslationsMap=gt,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[G.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const r=e[t];if(!r.firstChange&&r.currentValue!==r.previousValue&&r.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){Y(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([G.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[G.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(G.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return r=>{t||(t=[Object.keys(r.controls)]);return r?.controls&&t.some((t=>t.every((t=>!e(r.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",Wt),Wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Wt,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:D,useExisting:o((()=>Wt)),multi:!0},{provide:V,useExisting:o((()=>Wt)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:R.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:R.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Te.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,decorators:[{type:r,args:[{selector:"tb-credentials-config",providers:[{provide:D,useExisting:o((()=>Wt)),multi:!0},{provide:V,useExisting:o((()=>Wt)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});class Xt{}e("RulenodeCoreConfigCommonModule",Xt),Xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Xt.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Xt,declarations:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t],imports:[w,v,Ne],exports:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t]}),Xt.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,imports:[w,v,Ne]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,decorators:[{type:l,args:[{declarations:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t],imports:[w,v,Ne],exports:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t]}]}]});class Zt{}e("RuleNodeCoreConfigActionModule",Zt),Zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Zt.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Zt,declarations:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t],imports:[w,v,Ne,Xt],exports:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t]}),Zt.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,imports:[w,v,Ne,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,decorators:[{type:l,args:[{declarations:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t],imports:[w,v,Ne,Xt],exports:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t]}]}]});class er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e?e.inputValueKey:null,[G.required]],outputValueKey:[e?e.outputValueKey:null,[G.required]],useCache:[e?e.useCache:null,[]],addPeriodBetweenMsgs:[!!e&&e.addPeriodBetweenMsgs,[]],periodValueKey:[e?e.periodValueKey:null,[]],round:[e?e.round:null,[G.min(0),G.max(15)]],tellFailureIfDeltaIsNegative:[e?e.tellFailureIfDeltaIsNegative:null,[]]})}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([G.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:er,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:'
\n
\n \n tb.rulenode.input-value-key\n \n \n {{ \'tb.rulenode.input-value-key-required\' | translate }}\n \n \n \n tb.rulenode.output-value-key\n \n \n {{ \'tb.rulenode.output-value-key-required\' | translate }}\n \n \n \n tb.rulenode.round\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n
\n \n {{ \'tb.rulenode.use-cache\' | translate }}\n \n \n {{ \'tb.rulenode.tell-failure-if-delta-is-negative\' | translate }}\n \n \n {{ \'tb.rulenode.add-period-between-msgs\' | translate }}\n \n \n tb.rulenode.period-value-key\n \n \n {{ \'tb.rulenode.period-value-key-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,decorators:[{type:r,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:'
\n
\n \n tb.rulenode.input-value-key\n \n \n {{ \'tb.rulenode.input-value-key-required\' | translate }}\n \n \n \n tb.rulenode.output-value-key\n \n \n {{ \'tb.rulenode.output-value-key-required\' | translate }}\n \n \n \n tb.rulenode.round\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n
\n \n {{ \'tb.rulenode.use-cache\' | translate }}\n \n \n {{ \'tb.rulenode.tell-failure-if-delta-is-negative\' | translate }}\n \n \n {{ \'tb.rulenode.add-period-between-msgs\' | translate }}\n \n \n tb.rulenode.period-value-key\n \n \n {{ \'tb.rulenode.period-value-key-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.customerAttributesConfigForm}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("CustomerAttributesConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tr,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e?e.deviceRelationsQuery:null,[G.required]],tellFailureIfAbsent:[!!e&&e.tellFailureIfAbsent,[]],fetchToData:[!!e&&e.fetchToData,[]],clientAttributeNames:[e?e.clientAttributeNames:null,[]],sharedAttributeNames:[e?e.sharedAttributeNames:null,[]],serverAttributeNames:[e?e.serverAttributeNames:null,[]],latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],getLatestValueWithTs:[!!e&&e.getLatestValueWithTs,[]]})}removeKey(e,t){const r=this.deviceAttributesConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.deviceAttributesConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deviceAttributesConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deviceAttributesConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}prepareInputConfig(e){return W(e)&&X(e?.fetchToData)&&(e.fetchToData=!1),e}}e("DeviceAttributesConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rr,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Jt,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n \n \n \n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class nr extends s{constructor(e,t,r){super(e),this.store=e,this.translate=t,this.fb=r,this.entityDetailsTranslationsMap=st,this.entityDetailsList=[],this.searchText="",this.displayDetailsFn=this.displayDetails.bind(this);for(const e of Object.keys(lt))this.entityDetailsList.push(lt[e]);this.detailsFormControl=new P(""),this.filteredEntityDetails=this.detailsFormControl.valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchEntityDetails(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){return this.searchText="",this.detailsFormControl.patchValue("",{emitEvent:!0}),this.detailsList=e?e.detailsList:[],e}prepareOutputConfig(e){return e.detailsList=this.detailsList,e}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e?e.detailsList:null,[G.required]],addToMetadata:[!!e&&e.addToMetadata,[]]}),this.detailsList=e?e.detailsList:[]}displayDetails(e){return e?this.translate.instant(st.get(e)):void 0}fetchEntityDetails(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(this.entityDetailsList.filter((t=>this.translate.instant(st.get(lt[t])).toUpperCase().includes(e))))}return ke(this.entityDetailsList)}detailsFieldSelected(e){this.addDetailsField(e.option.value),this.clear("")}removeDetailsField(e){const t=this.detailsList.indexOf(e);t>=0&&(this.detailsList.splice(t,1),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}addDetailsField(e){this.detailsList||(this.detailsList=[]);-1===this.detailsList.indexOf(e)&&(this.detailsList.push(e),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}onEntityDetailsInputFocus(){this.detailsFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.detailsInput.nativeElement.value=e,this.detailsFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}}e("EntityDetailsConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,deps:[{token:M.Store},{token:U.TranslateService},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nr,selector:"tb-enrichment-node-entity-details-config",viewQueries:[{propertyName:"detailsInput",first:!0,predicate:["detailsInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.entity-details\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-entity-details-matching\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n {{ \'tb.rulenode.add-to-metadata\' | translate }}\n \n
tb.rulenode.add-to-metadata-hint
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n tb.rulenode.entity-details\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-entity-details-matching\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n {{ \'tb.rulenode.add-to-metadata\' | translate }}\n \n
tb.rulenode.add-to-metadata-hint
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:A.UntypedFormBuilder}]},propDecorators:{detailsInput:[{type:a,args:["detailsInput",{static:!1}]}]}});class ar extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe],this.aggregationTypes=L,this.aggregations=Object.keys(L),this.aggregationTypesTranslations=k,this.fetchMode=mt,this.fetchModes=Object.keys(mt),this.samplingOrders=Object.keys(pt),this.timeUnits=Object.values(nt),this.timeUnitsTranslationMap=at}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],aggregation:[e?e.aggregation:null,[G.required]],fetchMode:[e?e.fetchMode:null,[G.required]],orderBy:[e?e.orderBy:null,[]],limit:[e?e.limit:null,[]],useMetadataIntervalPatterns:[!!e&&e.useMetadataIntervalPatterns,[]],startInterval:[e?e.startInterval:null,[]],startIntervalTimeUnit:[e?e.startIntervalTimeUnit:null,[]],endInterval:[e?e.endInterval:null,[]],endIntervalTimeUnit:[e?e.endIntervalTimeUnit:null,[]],startIntervalPattern:[e?e.startIntervalPattern:null,[]],endIntervalPattern:[e?e.endIntervalPattern:null,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,r=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===mt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([G.required,G.min(2),G.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),r?(this.getTelemetryFromDatabaseConfigForm.get("startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([G.required])):(this.getTelemetryFromDatabaseConfigForm.get("startInterval").setValidators([G.required,G.min(1),G.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("endInterval").setValidators([G.required,G.min(1),G.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const r=this.getTelemetryFromDatabaseConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}}e("GetTelemetryFromDatabaseConfigComponent",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ar,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeseries-key\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.fetch-mode\n \n \n {{ mode }}\n \n \n tb.rulenode.fetch-mode-hint\n \n
\n \n aggregation.function\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n \n tb.rulenode.order-by\n \n \n {{ order }}\n \n \n tb.rulenode.order-by-hint\n \n \n tb.rulenode.limit\n \n tb.rulenode.limit-hint\n \n
\n \n {{ \'tb.rulenode.use-metadata-interval-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-interval-patterns-hint
\n
\n
\n \n tb.rulenode.start-interval\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.start-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.end-interval\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.end-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n \n tb.rulenode.start-interval-pattern\n \n \n {{ \'tb.rulenode.start-interval-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.end-interval-pattern\n \n \n {{ \'tb.rulenode.end-interval-pattern-required\' | translate }}\n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,decorators:[{type:r,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n tb.rulenode.timeseries-key\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.fetch-mode\n \n \n {{ mode }}\n \n \n tb.rulenode.fetch-mode-hint\n \n
\n \n aggregation.function\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n \n tb.rulenode.order-by\n \n \n {{ order }}\n \n \n tb.rulenode.order-by-hint\n \n \n tb.rulenode.limit\n \n tb.rulenode.limit-hint\n \n
\n \n {{ \'tb.rulenode.use-metadata-interval-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-interval-patterns-hint
\n
\n
\n \n tb.rulenode.start-interval\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.start-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.end-interval\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.end-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n \n tb.rulenode.start-interval-pattern\n \n \n {{ \'tb.rulenode.start-interval-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.end-interval-pattern\n \n \n {{ \'tb.rulenode.end-interval-pattern-required\' | translate }}\n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[!!e&&e.tellFailureIfAbsent,[]],fetchToData:[!!Y(e?.fetchToData)&&e.fetchToData,[]],clientAttributeNames:[e?e.clientAttributeNames:null,[]],sharedAttributeNames:[e?e.sharedAttributeNames:null,[]],serverAttributeNames:[e?e.serverAttributeNames:null,[]],latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],getLatestValueWithTs:[!!e&&e.getLatestValueWithTs,[]]})}removeKey(e,t){const r=this.originatorAttributesConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.originatorAttributesConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.originatorAttributesConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.originatorAttributesConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}prepareInputConfig(e){return W(e)&&X(e?.fetchToData)&&(e.fetchToData=!1),e}}e("OriginatorAttributesConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:or,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,decorators:[{type:r,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.originatorFieldsConfigForm}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({fieldsMapping:[e?e.fieldsMapping:null,[G.required]],ignoreNullStrings:[e?e.ignoreNullStrings:null]})}}e("OriginatorFieldsConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ir,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n {{ "tb.rulenode.ignore-null-strings" | translate }}\n
{{ "tb.rulenode.ignore-null-strings-hint" | translate }}
\n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,decorators:[{type:r,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n {{ "tb.rulenode.ignore-null-strings" | translate }}\n
{{ "tb.rulenode.ignore-null-strings-hint" | translate }}
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class lr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.relatedAttributesConfigForm}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e?e.relationsQuery:null,[G.required]],telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("RelatedAttributesConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:lr,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"component",type:Qt,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n \n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class sr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.tenantAttributesConfigForm}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("TenantAttributesConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:sr,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class mr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchToMetadata:[e?e.fetchToMetadata:null,[]]})}}e("FetchDeviceCredentialsConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:mr,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n {{ \'tb.rulenode.fetch-credentials-to-metadata\' | translate }}\n
\n',dependencies:[{kind:"component",type:De.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,decorators:[{type:r,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n {{ \'tb.rulenode.fetch-credentials-to-metadata\' | translate }}\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class ur{}e("RulenodeCoreConfigEnrichmentModule",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:ur,declarations:[tr,nr,rr,or,ir,ar,lr,sr,er,mr],imports:[w,v,Xt],exports:[tr,nr,rr,or,ir,ar,lr,sr,er,mr]}),ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ur,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ur,decorators:[{type:l,args:[{declarations:[tr,nr,rr,or,ir,ar,lr,sr,er,mr],imports:[w,v,Xt],exports:[tr,nr,rr,or,ir,ar,lr,sr,er,mr]}]}]});class pr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=yt,this.azureIotHubCredentialsTypeTranslationsMap=xt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[G.required,G.min(1),G.max(200)]],clientId:[e?e.clientId:null,[G.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[G.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),r=t.get("type").value;switch(e&&t.reset({type:r},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),r){case"sas":t.get("sasKey").setValidators([G.required]);break;case"cert.PEM":t.get("privateKey").setValidators([G.required]),t.get("privateKeyFileName").setValidators([G.required]),t.get("cert").setValidators([G.required]),t.get("certFileName").setValidators([G.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:pr,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:R.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:R.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Te.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:A.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pr,decorators:[{type:r,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class dr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=ht,this.ToByteStandartCharsetTypeTranslationMap=Ct}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[G.required]],retries:[e?e.retries:null,[G.min(0)]],batchSize:[e?e.batchSize:null,[G.min(0)]],linger:[e?e.linger:null,[G.min(0)]],bufferMemory:[e?e.bufferMemory:null,[G.min(0)]],acks:[e?e.acks:null,[G.required]],keySerializer:[e?e.keySerializer:null,[G.required]],valueSerializer:[e?e.valueSerializer:null,[G.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([G.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:dr,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dr,decorators:[{type:r,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class cr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[]}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[G.required,G.min(1),G.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&Z(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]}),this.subscriptions.push(this.mqttConfigForm.get("clientId").valueChanges.subscribe((e=>{Z(e)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1})})))}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}}e("MqttConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:cr,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Wt,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cr,decorators:[{type:r,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class fr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=I,this.entityType=x}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[G.required]],targets:[e?e.targets:[],[G.required]]})}}e("NotificationConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fr,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:fr,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:Ve.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Pe.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","disabled","notificationTypes"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fr,decorators:[{type:r,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]}});class gr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[G.required]],topicName:[e?e.topicName:null,[G.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[G.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[G.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:gr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gr,decorators:[{type:r,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class yr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[G.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[G.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:yr,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yr,decorators:[{type:r,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class xr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(bt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[G.required]],requestMethod:[e?e.requestMethod:null,[G.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],trimDoubleQuotes:[!!e&&e.trimDoubleQuotes,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[G.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,r=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,n=this.restApiCallConfigForm.get("enableProxy").value,a=this.restApiCallConfigForm.get("useSystemProxyProperties").value;n&&!a?(this.restApiCallConfigForm.get("proxyHost").setValidators(n?[G.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(n?[G.required,G.min(1),G.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([G.min(0)])),r?this.restApiCallConfigForm.get("maxQueueSize").setValidators([G.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:xr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"component",type:Wt,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xr,decorators:[{type:r,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class br extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,r=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([G.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([G.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([G.required,G.min(1),G.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([G.required,G.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(r?[G.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(r?[G.required,G.min(1),G.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:br,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:br,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Re.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:br,decorators:[{type:r,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class hr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[G.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[G.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([G.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:hr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:we.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hr,decorators:[{type:r,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Cr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(T),this.slackChanelTypesTranslateMap=N}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[G.required]],conversationType:[e?e.conversationType:null,[G.required]],conversation:[e?e.conversation:null,[G.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([G.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cr,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Cr,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Oe.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cr,decorators:[{type:r,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]}});class Fr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[G.required]],accessKeyId:[e?e.accessKeyId:null,[G.required]],secretAccessKey:[e?e.secretAccessKey:null,[G.required]],region:[e?e.region:null,[G.required]]})}}e("SnsConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Fr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fr,decorators:[{type:r,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class vr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=dt,this.sqsQueueTypes=Object.keys(dt),this.sqsQueueTypeTranslationsMap=ct}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[G.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[G.required]],delaySeconds:[e?e.delaySeconds:null,[G.min(0),G.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[G.required]],secretAccessKey:[e?e.secretAccessKey:null,[G.required]],region:[e?e.region:null,[G.required]]})}}e("SqsConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:vr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vr,decorators:[{type:r,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Lr{}e("RulenodeCoreConfigExternalModule",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Lr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Lr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Lr,declarations:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr],imports:[w,v,Ne,Xt],exports:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr]}),Lr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Lr,imports:[w,v,Ne,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Lr,decorators:[{type:l,args:[{declarations:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr],imports:[w,v,Ne,Xt],exports:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr]}]}]});class kr extends s{constructor(e,t,r){super(e),this.store=e,this.translate=t,this.fb=r,this.alarmStatusTranslationsMap=q,this.alarmStatusList=[],this.searchText="",this.displayStatusFn=this.displayStatus.bind(this);for(const e of Object.keys(S))this.alarmStatusList.push(S[e]);this.statusFormControl=new P(""),this.filteredAlarmStatus=this.statusFormControl.valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchAlarmStatus(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return this.searchText="",this.statusFormControl.patchValue("",{emitEvent:!0}),e}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e?e.alarmStatusList:null,[G.required]]})}displayStatus(e){return e?this.translate.instant(q.get(e)):void 0}fetchAlarmStatus(e){const t=this.getAlarmStatusList();if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(t.filter((t=>this.translate.instant(q.get(S[t])).toUpperCase().includes(e))))}return ke(t)}alarmStatusSelected(e){this.addAlarmStatus(e.option.value),this.clear("")}removeAlarmStatus(e){const t=this.alarmStatusConfigForm.get("alarmStatusList").value;if(t){const r=t.indexOf(e);r>=0&&(t.splice(r,1),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}}addAlarmStatus(e){let t=this.alarmStatusConfigForm.get("alarmStatusList").value;t||(t=[]);-1===t.indexOf(e)&&(t.push(e),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}getAlarmStatusList(){return this.alarmStatusList.filter((e=>-1===this.alarmStatusConfigForm.get("alarmStatusList").value.indexOf(e)))}onAlarmStatusInputFocus(){this.statusFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.alarmStatusInput.nativeElement.value=e,this.statusFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.alarmStatusInput.nativeElement.blur(),this.alarmStatusInput.nativeElement.focus()}),0)}}e("CheckAlarmStatusComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kr,deps:[{token:M.Store},{token:U.TranslateService},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:kr,selector:"tb-filter-node-check-alarm-status-config",viewQueries:[{propertyName:"alarmStatusInput",first:!0,predicate:["alarmStatusInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kr,decorators:[{type:r,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:A.UntypedFormBuilder}]},propDecorators:{alarmStatusInput:[{type:a,args:["alarmStatusInput",{static:!1}]}]}});class Ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.checkMessageConfigForm}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e?e.messageNames:null,[]],metadataNames:[e?e.metadataNames:null,[]],checkAllKeys:[!!e&&e.checkAllKeys,[]]})}validateConfig(){const e=this.checkMessageConfigForm.get("messageNames").value,t=this.checkMessageConfigForm.get("metadataNames").value;return e.length>0||t.length>0}removeMessageName(e){const t=this.checkMessageConfigForm.get("messageNames").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.checkMessageConfigForm.get("messageNames").setValue(t,{emitEvent:!0}))}removeMetadataName(e){const t=this.checkMessageConfigForm.get("metadataNames").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.checkMessageConfigForm.get("metadataNames").setValue(t,{emitEvent:!0}))}addMessageName(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.checkMessageConfigForm.get("messageNames").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.checkMessageConfigForm.get("messageNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}addMetadataName(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.checkMessageConfigForm.get("metadataNames").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.checkMessageConfigForm.get("metadataNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CheckMessageConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ir,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ir,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ir,decorators:[{type:r,args:[{selector:"tb-filter-node-check-message-config",template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.keys(g),this.entitySearchDirectionTranslationsMap=y}configForm(){return this.checkRelationConfigForm}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[!!e&&e.checkForSingleEntity,[]],direction:[e?e.direction:null,[]],entityType:[e?e.entityType:null,e&&e.checkForSingleEntity?[G.required]:[]],entityId:[e?e.entityId:null,e&&e.checkForSingleEntity?[G.required]:[]],relationType:[e?e.relationType:null,[G.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[G.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[G.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Tr,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Se.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["required","disabled","subscriptSizing"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tr,decorators:[{type:r,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Nr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=tt,this.perimeterTypes=Object.keys(tt),this.perimeterTypeTranslationMap=rt,this.rangeUnits=Object.keys(ot),this.rangeUnitTranslationMap=it}configForm(){return this.geoFilterConfigForm}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[G.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[G.required]],perimeterType:[e?e.perimeterType:null,[G.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,r=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([G.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||r!==tt.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([])):(this.geoFilterConfigForm.get("centerLatitude").setValidators([G.required,G.min(-90),G.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([G.required,G.min(-180),G.max(180)]),this.geoFilterConfigForm.get("range").setValidators([G.required,G.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([G.required])),t||r!==tt.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([G.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",Nr),Nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Nr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nr,decorators:[{type:r,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class qr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e?e.messageTypes:null,[G.required]]})}}e("MessageTypeConfigComponent",qr),qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),qr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:qr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Yt,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qr,decorators:[{type:r,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Sr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.TENANT,x.CUSTOMER,x.USER,x.DASHBOARD,x.RULE_CHAIN,x.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e?e.originatorTypes:null,[G.required]]})}}e("OriginatorTypeConfigComponent",Sr),Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Sr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n
\n',dependencies:[{kind:"component",type:Ke.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","disabled","subscriptSizing","allowedEntityTypes","ignoreAuthorityFilter"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sr,decorators:[{type:r,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Mr extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",n=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Mr),Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mr,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Mr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mr,decorators:[{type:r,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Ar extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.switchConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",n=this.switchConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.switchConfigForm.get(t).setValue(e)}))}onValidate(){this.switchConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Ar),Ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ar,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ar,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ar,decorators:[{type:r,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Gr{}e("RuleNodeCoreConfigFilterModule",Gr),Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Gr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Gr,declarations:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr],imports:[w,v,Xt],exports:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr]}),Gr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gr,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gr,decorators:[{type:l,args:[{declarations:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr],imports:[w,v,Xt],exports:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr]}]}]});class Er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=Ze,this.originatorSources=Object.keys(Ze),this.originatorSourceTranslationMap=et,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.USER,x.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[G.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===Ze.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([G.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===Ze.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([G.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Er),Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Er,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Er,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Er,decorators:[{type:r,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Dr extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[G.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",n=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Dr),Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dr,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Dr,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dr,decorators:[{type:r,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Vr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",value:"false"},{name:"tb.mail-body-type.html",value:"true"},{name:"tb.mail-body-type.dynamic",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[G.required]],toTemplate:[e?e.toTemplate:null,[G.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[G.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null],bodyTemplate:[e?e.bodyTemplate:null,[G.required]]}),this.toEmailConfigForm.get("mailBodyType").valueChanges.pipe(Ce([e?.subjectTemplate])).subscribe((e=>{"dynamic"===e?(this.toEmailConfigForm.get("isHtmlTemplate").patchValue("",{emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").setValidators(G.required)):this.toEmailConfigForm.get("isHtmlTemplate").clearValidators(),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity()}))}}e("ToEmailConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Vr,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vr,decorators:[{type:r,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Pr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],keys:[e?e.keys:null,[G.required]]})}configForm(){return this.copyKeysConfigForm}removeKey(e){const t=this.copyKeysConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.copyKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.copyKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.copyKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CopyKeysConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Pr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pr,decorators:[{type:r,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[G.required]]})}}e("RenameKeysConfigComponent",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Rr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rr,decorators:[{type:r,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class wr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[G.required]]})}}e("NodeJsonPathConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:wr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n",dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wr,decorators:[{type:r,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n"}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],keys:[e?e.keys:null,[G.required]]})}configForm(){return this.deleteKeysConfigForm}removeKey(e){const t=this.deleteKeysConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.deleteKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.deleteKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.deleteKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteKeysConfigComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Or,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Or,decorators:[{type:r,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Hr{}e("RulenodeCoreConfigTransformModule",Hr),Hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Hr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Hr,declarations:[Er,Dr,Vr,Pr,Rr,wr,Or],imports:[w,v,Xt],exports:[Er,Dr,Vr,Pr,Rr,wr,Or]}),Hr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hr,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hr,decorators:[{type:l,args:[{declarations:[Er,Dr,Vr,Pr,Rr,wr,Or],imports:[w,v,Xt],exports:[Er,Dr,Vr,Pr,Rr,wr,Or]}]}]});class Kr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=x}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[G.required]]})}}e("RuleChainInputComponent",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kr,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:He.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kr,decorators:[{type:r,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Br extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Br,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Br,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Br,decorators:[{type:r,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ur{}e("RuleNodeCoreConfigFlowModule",Ur),Ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Ur,declarations:[Kr,Br],imports:[w,v,Xt],exports:[Kr,Br]}),Ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ur,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ur,decorators:[{type:l,args:[{declarations:[Kr,Br],imports:[w,v,Xt],exports:[Kr,Br]}]}]});class zr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{"create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","output-message-type":"Output message type","output-message-type-required":"Output message type is required","output-message-type-max-length":"Output message type should be less than 256","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","start-interval":"Start Interval","end-interval":"End Interval","start-interval-time-unit":"Start Interval Time Unit","end-interval-time-unit":"End Interval Time Unit","fetch-mode":"Fetch mode","fetch-mode-hint":"If selected fetch mode 'ALL' you able to choose telemetry sampling order.","order-by":"Order by","order-by-hint":"Select to choose telemetry sampling order.",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. In case you want to fetch a single entry, select fetch mode 'FIRST' or 'LAST'.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Time value should be in a range from 1 to 2147483647.","start-interval-value-required":"Start interval value is required.","end-interval-value-required":"End interval value is required.",filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attribute keys","shared-attributes":"Shared attribute keys","server-attributes":"Server attribute keys","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Notify device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-hint":"If the message arrives from the device, we will push it back to the device by default.","notify-device-delete-hint":"Send notification about deleted attributes to device.","latest-timeseries":"Latest time-series data keys","timeseries-key":"Time-series key","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Hint: use regular expression to copy keys by pattern",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.","first-message":"First Message","last-message":"Last Message","all-messages":"All Messages","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",metadata:"Metadata","key-name":"Key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern","fetch-into":"Fetch into","attr-mapping":"Attributes mapping","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-attribute":"Target attribute","target-attribute-required":"Target attribute is required.","attr-mapping-required":"At least one attribute mapping should be specified.","fields-mapping":"Fields mapping","fields-mapping-required":"At least one field mapping should be specified.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","body-template":"Body Template","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","trim-double-quotes":"Message without quotes","trim-double-quotes-hint":"If selected, request body message payload will be sent without double quotes, i.e. msg = message body","read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Hint: Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Hint: Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Hint: Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-interval-patterns":"Use interval patterns","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval-pattern":"Start interval pattern","end-interval-pattern":"End interval pattern","start-interval-pattern-required":"Start interval pattern is required","end-interval-pattern-required":"End interval pattern is required","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"entity-details":"Select entity details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","add-to-metadata":"Add selected details to message metadata","add-to-metadata-hint":"If selected, adds the selected details keys to the message metadata instead of message data.","entity-details-list-empty":"No entity details selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-key-name":"Latitude key name","longitude-key-name":"Longitude key name","latitude-key-name-required":"Latitude key name is required.","longitude-key-name-required":"Longitude key name is required.","fetch-perimeter-info-from-message-metadata":"Fetch perimeter information from message metadata","perimeter-key-name":"Perimeter key name","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Please, use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.",round:"Decimals","round-range":"Decimals should be in a range from 0 to 15.","use-cache":"Use cache for latest value","tell-failure-if-delta-is-negative":"Tell Failure if delta is negative","add-period-between-msgs":"Add period between messages","period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"alarm-severity-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body to substitute "Source" and "Target" key names',"shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time series","message-body-type":"Message body","message-metadata-type":"Message metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-type-field-input":"Type","argument-type-field-input-required":"Argument type is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Hint: use 0 to convert result to integer","add-to-body-field-input":"Add to message body","add-to-metadata-field-input":"Add to message metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Hint: specify a mathematical expression to evaluate. For example, transform Fahrenheit to Celsius using (x - 32) / 1.8)","retained-message":"Retained","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required"},"key-val":{key:"Key",value:"Value","remove-entry":"Remove entry","add-entry":"Add entry","unique-key-value-pair-error":"'{{valText}}' must be different from the current '{{keyText}}'"},"mail-body-type":{"plain-text":"Plain Text",html:"HTML",dynamic:"Dynamic"}}},!0)}(e)}}e("RuleNodeCoreConfigModule",zr),zr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zr,deps:[{token:U.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),zr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:zr,declarations:[Be],imports:[w,v],exports:[Zt,Gr,ur,Lr,Hr,Ur,Be]}),zr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zr,imports:[w,v,Zt,Gr,ur,Lr,Hr,Ur]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zr,decorators:[{type:l,args:[{declarations:[Be],imports:[w,v],exports:[Zt,Gr,ur,Lr,Hr,Ur,Be]}]}],ctorParameters:function(){return[{type:U.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map +System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/platform-browser","@angular/material/select","@angular/material/core","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/icon","@angular/material/chips","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/material/tooltip","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","rxjs","@angular/material/expansion","@home/components/public-api","tslib","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@angular/material/slide-toggle","@home/components/relation/relation-filters.component","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@angular/material/button-toggle","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,u,p,d,c,f,g,y,x,b,h,C,v,F,L,k,T,I,N,S,q,M,A,G,E,D,V,w,P,R,O,H,K,B,U,z,_,j,$,Q,J,Y,W,X,Z,ee,te,ne,re,oe,ae,ie,le,se,me,ue,pe,de,ce,fe,ge,ye,xe,be,he,Ce,ve,Fe,Le,ke,Te,Ie,Ne,Se,qe,Me,Ae,Ge,Ee,De,Ve,we,Pe,Re,Oe,He,Ke,Be,Ue,ze,_e,je;return{setters:[function(e){t=e,n=e.Component,r=e.Pipe,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.NgModule},function(e){s=e.RuleNodeConfigurationComponent,m=e.AttributeScope,u=e.telemetryTypeTranslations,p=e.ServiceType,d=e.ScriptLanguage,c=e.AlarmSeverity,f=e.alarmSeverityTranslations,g=e.EntitySearchDirection,y=e.entitySearchDirectionTranslations,x=e.EntityType,b=e.PageComponent,h=e.coerceBoolean,C=e.MessageType,v=e.messageTypeNames,F=e,L=e.SharedModule,k=e.AggregationType,T=e.aggregationTranslations,I=e.NotificationType,N=e.SlackChanelType,S=e.SlackChanelTypesTranslateMap,q=e.alarmStatusTranslations,M=e.AlarmStatus},function(e){A=e},function(e){G=e,E=e.Validators,D=e.NgControl,V=e.NG_VALUE_ACCESSOR,w=e.NG_VALIDATORS,P=e.FormControl,R=e.UntypedFormControl},function(e){O=e,H=e.CommonModule},function(e){K=e},function(e){B=e},function(e){U=e},function(e){z=e},function(e){_=e},function(e){j=e},function(e){$=e},function(e){Q=e},function(e){J=e},function(e){Y=e.getCurrentAuthState,W=e,X=e.isDefinedAndNotNull,Z=e.isObject,ee=e.isNotEmptyStr},function(e){te=e},function(e){ne=e},function(e){re=e},function(e){oe=e.ENTER,ae=e.COMMA,ie=e.SEMICOLON},function(e){le=e},function(e){se=e},function(e){me=e},function(e){ue=e},function(e){pe=e.coerceBooleanProperty},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e},function(e){xe=e.tap,be=e.map,he=e.mergeMap,Ce=e.takeUntil,ve=e.startWith,Fe=e.share,Le=e.distinctUntilChanged},function(e){ke=e},function(e){Te=e},function(e){Ie=e.of,Ne=e.Subject},function(e){Se=e},function(e){qe=e.HomeComponentsModule},function(e){Me=e.__decorate},function(e){Ae=e},function(e){Ge=e},function(e){Ee=e},function(e){De=e},function(e){Ve=e},function(e){we=e},function(e){Pe=e},function(e){Re=e},function(e){Oe=e},function(e){He=e},function(e){Ke=e},function(e){Be=e},function(e){Ue=e},function(e){ze=e},function(e){_e=e},function(e){je=e}],execute:function(){class $e extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",$e),$e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$e,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qe{constructor(e){this.sanitizer=e}transform(e){return this.sanitizer.bypassSecurityTrustHtml(e)}}e("SafeHtmlPipe",Qe),Qe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,deps:[{token:j.DomSanitizer}],target:t.ɵɵFactoryTarget.Pipe}),Qe.ɵpipe=t.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Qe,name:"safeHtml"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,decorators:[{type:r,args:[{name:"safeHtml"}]}],ctorParameters:function(){return[{type:j.DomSanitizer}]}});class Je extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[E.required,E.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[E.required,E.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",Je),Je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Je,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Ye extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===m.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",Ye),Ye.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ye.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ye,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class We extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[E.required]]})}}e("CheckPointConfigComponent",We),We.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),We.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:We,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,decorators:[{type:n,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Xe extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[E.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===d.JS?[E.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===d.TBEL?[E.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.clearAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",r=this.clearAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.clearAlarmConfigForm.get(t).setValue(e)}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",Xe),Xe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xe,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Ze extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.alarmSeverities=Object.keys(c),this.alarmSeverityTranslationMap=f,this.separatorKeysCodes=[oe,ae,ie],this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([E.required]),this.createAlarmConfigForm.get("severity").setValidators([E.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==d.TBEL||this.tbelEnabled||(r=d.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===d.JS?[E.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===d.TBEL?[E.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.createAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",r=this.createAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.createAlarmConfigForm.get(t).setValue(e)}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",Ze),Ze.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ze,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ze.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ze,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ze,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class et extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[E.required]],entityType:[e?e.entityType:null,[E.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[E.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[E.required,E.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==x.DEVICE&&t!==x.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([E.required,E.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",et),et.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:et,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),et.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:et,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:et,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class tt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[E.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[E.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[E.required,E.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([E.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",tt),tt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,E.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,E.required]})}}e("DeviceProfileConfigComponent",nt),nt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class rt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[E.required,E.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[E.required,E.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(){const e=this.generatorConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",r=this.generatorConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.generatorConfigForm.get(t).setValue(e)}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}var ot;e("GeneratorConfigComponent",rt),rt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rt,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),rt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rt,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rt,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(ot||(ot={}));const at=new Map([[ot.CUSTOMER,"tb.rulenode.originator-customer"],[ot.TENANT,"tb.rulenode.originator-tenant"],[ot.RELATED,"tb.rulenode.originator-related"],[ot.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[ot.ENTITY,"tb.rulenode.originator-entity"]]);var it;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(it||(it={}));const lt=new Map([[it.CIRCLE,"tb.rulenode.perimeter-circle"],[it.POLYGON,"tb.rulenode.perimeter-polygon"]]);var st;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(st||(st={}));const mt=new Map([[st.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[st.SECONDS,"tb.rulenode.time-unit-seconds"],[st.MINUTES,"tb.rulenode.time-unit-minutes"],[st.HOURS,"tb.rulenode.time-unit-hours"],[st.DAYS,"tb.rulenode.time-unit-days"]]);var ut;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(ut||(ut={}));const pt=new Map([[ut.METER,"tb.rulenode.range-unit-meter"],[ut.KILOMETER,"tb.rulenode.range-unit-kilometer"],[ut.FOOT,"tb.rulenode.range-unit-foot"],[ut.MILE,"tb.rulenode.range-unit-mile"],[ut.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var dt,ct;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(dt||(dt={})),function(e){e.NAME="name",e.CREATED_TIME="createdTime",e.TYPE="type",e.FIRST_NAME="firstName",e.LAST_NAME="lastName",e.EMAIL="email",e.TITLE="title",e.COUNTRY="county",e.STATE="state",e.CITY="city",e.ADDRESS="address",e.ADDRESS2="address2",e.ZIP="zip",e.PHONE="phone",e.LABEL="label"}(ct||(ct={}));const ft=new Map([[ct.NAME,"tb.rulenode.name"],[ct.CREATED_TIME,"tb.rulenode.created-time"],[ct.TYPE,"tb.rulenode.type"],[ct.FIRST_NAME,"tb.rulenode.first-name"],[ct.LAST_NAME,"tb.rulenode.last-name"],[ct.EMAIL,"tb.rulenode.entity-details-email"],[ct.TITLE,"tb.rulenode.entity-details-title"],[ct.COUNTRY,"tb.rulenode.entity-details-country"],[ct.STATE,"tb.rulenode.entity-details-state"],[ct.CITY,"tb.rulenode.entity-details-city"],[ct.ADDRESS,"tb.rulenode.entity-details-address"],[ct.ADDRESS2,"tb.rulenode.entity-details-address2"],[ct.ZIP,"tb.rulenode.entity-details-zip"],[ct.PHONE,"tb.rulenode.entity-details-phone"],[ct.LABEL,"tb.rulenode.label"]]),gt=new Map([[dt.ID,"tb.rulenode.entity-details-id"],[dt.TITLE,"tb.rulenode.entity-details-title"],[dt.COUNTRY,"tb.rulenode.entity-details-country"],[dt.STATE,"tb.rulenode.entity-details-state"],[dt.CITY,"tb.rulenode.entity-details-city"],[dt.ZIP,"tb.rulenode.entity-details-zip"],[dt.ADDRESS,"tb.rulenode.entity-details-address"],[dt.ADDRESS2,"tb.rulenode.entity-details-address2"],[dt.PHONE,"tb.rulenode.entity-details-phone"],[dt.EMAIL,"tb.rulenode.entity-details-email"],[dt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var yt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(yt||(yt={}));const xt=new Map([[yt.FIRST,"tb.rulenode.first"],[yt.LAST,"tb.rulenode.last"],[yt.ALL,"tb.rulenode.all"]]);var bt,ht;!function(e){e.ASC="ASC",e.DESC="DESC"}(bt||(bt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(ht||(ht={}));const Ct=new Map([[bt.ASC,"tb.rulenode.ascending"],[bt.DESC,"tb.rulenode.descending"]]);var vt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(vt||(vt={}));const Ft=new Map([[vt.STANDARD,"tb.rulenode.sqs-queue-standard"],[vt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),Lt=["anonymous","basic","cert.PEM"],kt=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Tt=["sas","cert.PEM"],It=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var Nt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(Nt||(Nt={}));const St=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],qt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Mt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Mt||(Mt={}));const At=new Map([[Mt.CUSTOM,{value:Mt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Mt.ADD,{value:Mt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Mt.SUB,{value:Mt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Mt.MULT,{value:Mt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Mt.DIV,{value:Mt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Mt.SIN,{value:Mt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Mt.SINH,{value:Mt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Mt.COS,{value:Mt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Mt.COSH,{value:Mt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Mt.TAN,{value:Mt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Mt.TANH,{value:Mt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Mt.ACOS,{value:Mt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Mt.ASIN,{value:Mt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Mt.ATAN,{value:Mt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Mt.ATAN2,{value:Mt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Mt.EXP,{value:Mt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Mt.EXPM1,{value:Mt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Mt.SQRT,{value:Mt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Mt.CBRT,{value:Mt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Mt.GET_EXP,{value:Mt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Mt.HYPOT,{value:Mt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Mt.LOG,{value:Mt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Mt.LOG10,{value:Mt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Mt.LOG1P,{value:Mt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Mt.CEIL,{value:Mt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Mt.FLOOR,{value:Mt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Mt.FLOOR_DIV,{value:Mt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Mt.FLOOR_MOD,{value:Mt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Mt.ABS,{value:Mt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Mt.MIN,{value:Mt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Mt.MAX,{value:Mt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Mt.POW,{value:Mt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Mt.SIGNUM,{value:Mt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Mt.RAD,{value:Mt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Mt.DEG,{value:Mt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Gt,Et,Dt;!function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Gt||(Gt={})),function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Et||(Et={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(Dt||(Dt={}));const Vt=new Map([[Gt.ATTRIBUTE,"tb.rulenode.attribute-type"],[Gt.TIME_SERIES,"tb.rulenode.time-series-type"],[Gt.CONSTANT,"tb.rulenode.constant-type"],[Gt.MESSAGE_BODY,"tb.rulenode.message-body-type"],[Gt.MESSAGE_METADATA,"tb.rulenode.message-metadata-type"]]),wt=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var Pt,Rt;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(Pt||(Pt={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(Rt||(Rt={}));const Ot=new Map([[Pt.SHARED_SCOPE,"tb.rulenode.shared-scope"],[Pt.SERVER_SCOPE,"tb.rulenode.server-scope"],[Pt.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class Ht extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=it,this.perimeterTypes=Object.keys(it),this.perimeterTypeTranslationMap=lt,this.rangeUnits=Object.keys(ut),this.rangeUnitTranslationMap=pt,this.timeUnits=Object.keys(st),this.timeUnitsTranslationMap=mt}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[E.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[E.required]],perimeterType:[e?e.perimeterType:null,[E.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[E.required,E.min(1),E.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[E.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[E.required,E.min(1),E.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[E.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([E.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==it.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([E.required,E.min(-90),E.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([E.required,E.min(-180),E.max(180)]),this.geoActionConfigForm.get("range").setValidators([E.required,E.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([E.required])),t||n!==it.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([E.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",Ht),Ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ht,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Kt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.logConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",r=this.logConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.logConfigForm.get(t).setValue(e)}))}onValidate(){this.logConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",Kt),Kt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Kt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kt,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Bt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[E.required,E.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[E.required]]})}}e("MsgCountConfigComponent",Bt),Bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Bt,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Ut extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[E.required,E.min(1),E.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([E.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([E.required,E.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",Ut),Ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ut,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class zt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]]})}}e("PushToCloudConfigComponent",zt),zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zt,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class _t extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]]})}}e("PushToEdgeConfigComponent",_t),_t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_t,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",jt),jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jt,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class $t extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[E.required,E.min(0)]]})}}e("RpcRequestConfigComponent",$t),$t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$t,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required]],value:[e[n],[E.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[E.required]],value:["",[E.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Qt),Qt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qt,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:V,useExisting:a((()=>Qt)),multi:!0},{provide:w,useExisting:a((()=>Qt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:V,useExisting:a((()=>Qt)),multi:!0},{provide:w,useExisting:a((()=>Qt)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class Jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[E.required,E.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[E.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",Jt),Jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jt,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Yt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[E.required,E.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Yt),Yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yt,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Wt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[E.required,E.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[E.required,E.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Wt),Wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Wt,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Xt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]],keys:[e?e.keys:null,[E.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",Xt),Xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xt,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Zt extends b{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup())}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=At,this.ArgumentType=Gt,this.attributeScopeMap=Ot,this.argumentTypeResultMap=Vt,this.arguments=Object.values(Gt),this.attributeScope=Object.values(Pt),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.argumentsFormGroup=this.fb.group({}),this.argumentsFormGroup.addControl("arguments",this.fb.array([])),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray(),n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):this.argumentsFormGroup.enable({emitEvent:!1})}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()));const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t)),this.setupArgumentsFormGroup(),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()})))}removeArgument(e){this.argumentsFormGroup.get("arguments").removeAt(e),this.updateArgumentNames()}addArgument(){const e=this.argumentsFormGroup.get("arguments"),t=this.createArgumentControl(null,e.length);e.push(t)}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Mt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([E.minLength(this.minArgs),E.maxLength(this.maxArgs)]),this.argumentsFormGroup.get("arguments").value.length>this.maxArgs&&(this.argumentsFormGroup.get("arguments").controls.length=this.maxArgs);this.argumentsFormGroup.get("arguments").value.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!0}),n.get("defaultValue").updateValueAndValidity({emitEvent:!0})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Gt.ATTRIBUTE?e.get("attributeScope").enable():e.get("attributeScope").disable(),t&&t!==Gt.CONSTANT?e.get("defaultValue").enable():e.get("defaultValue").disable()}updateArgumentNames(){this.argumentsFormGroup.get("arguments").controls.forEach(((e,t)=>{e.get("name").setValue(wt[t])}))}updateModel(){const e=this.argumentsFormGroup.get("arguments").value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Zt),Zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Zt,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:V,useExisting:a((()=>Zt)),multi:!0},{provide:w,useExisting:a((()=>Zt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"],dependencies:[{kind:"directive",type:O.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ge.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:ge.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:ye.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:ye.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:ye.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:V,useExisting:a((()=>Zt)),multi:!0},{provide:w,useExisting:a((()=>Zt)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class en extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...At.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(xe((e=>{let t;t="string"==typeof e&&Mt[e]?Mt[e]:null,this.updateView(t)})),be((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=At.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",en),en.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:en,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),en.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:en,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:V,useExisting:a((()=>en)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:en,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:V,useExisting:a((()=>en)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Mt,this.ArgumentTypeResult=Et,this.argumentTypeResultMap=Vt,this.attributeScopeMap=Ot,this.argumentsResult=Object.values(Et),this.attributeScopeResult=Object.values(Rt)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[E.required]],arguments:[e?e.arguments:null,[E.required]],customFunction:[e?e.customFunction:"",[E.required]],result:this.fb.group({type:[e?e.result.type:null,[E.required]],attributeScope:[e?e.result.attributeScope:null],key:[e?e.result.key:"",[E.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result").get("type").value;t===Mt.CUSTOM?this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Et.ATTRIBUTE?this.mathFunctionConfigForm.get("result").get("attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result").get("attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result").get("attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",tn),tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tn,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Zt,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:en,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tn,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nn{constructor(e,t){this.store=e,this.fb=t,this.subscriptSizing="fixed",this.searchText="",this.dirty=!1,this.messageTypes=["POST_ATTRIBUTES_REQUEST","POST_TELEMETRY_REQUEST"],this.propagateChange=e=>{},this.messageTypeFormGroup=this.fb.group({messageType:[null,[E.required,E.maxLength(255)]]})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.outputMessageTypes=this.messageTypeFormGroup.get("messageType").valueChanges.pipe(xe((e=>{this.updateView(e)})),be((e=>e||"")),he((e=>this.fetchMessageTypes(e))))}writeValue(e){this.searchText="",this.modelValue=e,this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1}),this.dirty=!0}onFocus(){this.dirty&&(this.messageTypeFormGroup.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0}),this.dirty=!1)}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}displayMessageTypeFn(e){return e||void 0}fetchMessageTypes(e,t=!1){return this.searchText=e,Ie(this.messageTypes).pipe(be((n=>n.filter((n=>t?!!e&&n===e:!e||n.toUpperCase().startsWith(e.toUpperCase()))))))}clear(){this.messageTypeFormGroup.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}}e("OutputMessageTypeAutocompleteComponent",nn),nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nn,selector:"tb-output-message-type-autocomplete",inputs:{autocompleteHint:"autocompleteHint",subscriptSizing:"subscriptSizing"},providers:[{provide:V,useExisting:a((()=>nn)),multi:!0}],viewQueries:[{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0,static:!0}],ngImport:t,template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:V,useExisting:a((()=>nn)),multi:!0}],template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{messageTypeInput:[{type:o,args:["messageTypeInput",{static:!0}]}],autocompleteHint:[{type:i}],subscriptSizing:[{type:i}]}});class rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.destroy$=new Ne,this.serviceType=p.TB_RULE_ENGINE,this.deduplicationStrategie=yt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=xt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[X(e?.interval)?e.interval:null,[E.required,E.min(1)]],strategy:[X(e?.strategy)?e.strategy:null,[E.required]],outMsgType:[X(e?.outMsgType)?e.outMsgType:null,[E.required]],queueName:[X(e?.queueName)?e.queueName:null,[E.required]],maxPendingMsgs:[X(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[E.required,E.min(1),E.max(1e3)]],maxRetries:[X(e?.maxRetries)?e.maxRetries:null,[E.required,E.min(0),E.max(100)]]}),this.deduplicationConfigForm.get("strategy").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.enableControl(e)}))}updateValidators(e){this.enableControl(this.deduplicationConfigForm.get("strategy").value)}validatorTriggers(){return["strategy"]}enableControl(e){e===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("DeduplicationConfigComponent",rn),rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rn,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:nn,selector:"tb-output-message-type-autocomplete",inputs:["autocompleteHint","subscriptSizing"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class on extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[e[n],[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",on),on.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:on,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),on.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:on,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:V,useExisting:a((()=>on)),multi:!0},{provide:w,useExisting:a((()=>on)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n \n \n \n
\n
\n {{ hintText }}\n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),Me([h()],on.prototype,"disabled",void 0),Me([h()],on.prototype,"uniqueKeyValuePairValidator",void 0),Me([h()],on.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:on,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:V,useExisting:a((()=>on)),multi:!0},{provide:w,useExisting:a((()=>on)),multi:!0}],template:'
\n
\n \n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n \n \n \n
\n
\n {{ hintText }}\n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class an{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne}ngOnInit(){this.slideToggleControlGroup=this.fb.group({slideToggleControl:[null,[]]}),this.slideToggleControlGroup.get("slideToggleControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.slideToggleControlGroup.get("slideToggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SlideToggleComponent",an),an.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:an,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),an.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:an,selector:"tb-slide-toggle",inputs:{slideToggleName:"slideToggleName",slideToggleTooltip:"slideToggleTooltip"},providers:[{provide:V,useExisting:a((()=>an)),multi:!0}],ngImport:t,template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"],dependencies:[{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:De.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:an,decorators:[{type:n,args:[{selector:"tb-slide-toggle",providers:[{provide:V,useExisting:a((()=>an)),multi:!0}],template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{slideToggleName:[{type:i}],slideToggleTooltip:[{type:i}]}});class ln extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[E.min(1)]],relationType:[null],deviceTypes:[null,[E.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",ln),ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ln,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ln,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>ln)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ge.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["label","required","disabled","entityType"]},{kind:"component",type:Ee.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","required","disabled","subscriptSizing"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ln,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:V,useExisting:a((()=>ln)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class sn{set required(e){this.requiredValue=pe(e)}get required(){return this.requiredValue}}e("FieldsetComponent",sn),sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sn,deps:[],target:t.ɵɵFactoryTarget.Component}),sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:sn,selector:"tb-fieldset-component",inputs:{label:"label",required:"required"},ngImport:t,template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sn,decorators:[{type:n,args:[{selector:"tb-fieldset-component",template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],propDecorators:{label:[{type:i}],required:[{type:i}]}});class mn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[E.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",mn),mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:mn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>mn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ve.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:V,useExisting:a((()=>mn)),multi:!0}],template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class un extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.message-type",this.separatorKeysCodes=[oe,ae,ie],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(C))this.messageTypesList.push({name:v.get(C[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchMessageTypes(e))),Fe())}ngAfterViewInit(){}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return!!(e&&null!=e&&e.length>0)}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ie(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t=null;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:un,deps:[{token:A.Store},{token:_.TranslateService},{token:F.TruncatePipe},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:un,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:V,useExisting:a((()=>un)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:V,useExisting:a((()=>un)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:F.TruncatePipe},{type:G.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class pn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRquired=!0,this.allCredentialsTypes=Lt,this.credentialsTypeTranslationsMap=kt,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[E.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.pipe(Le()).subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){X(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators(!1))}setDisabledState(e){e?this.credentialsConfigFormGroup.disable():(this.credentialsConfigFormGroup.enable(),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([E.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRquired?[E.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(E.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",pn),pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:pn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRquired:"passwordFieldRquired"},providers:[{provide:V,useExisting:a((()=>pn)),multi:!0},{provide:w,useExisting:a((()=>pn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:O.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:O.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Se.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:V,useExisting:a((()=>pn)),multi:!0},{provide:w,useExisting:a((()=>pn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRquired:[{type:i}]}});class dn{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne,this.fetchTo=Dt}ngOnInit(){this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("MsgMetadataChipComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:dn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText"},providers:[{provide:V,useExisting:a((()=>dn)),multi:!0}],ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.message\' | translate }}\n {{ \'tb.rulenode.metadata\' | translate }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"],dependencies:[{kind:"component",type:se.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:se.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:V,useExisting:a((()=>dn)),multi:!0}],template:'
\n \n \n {{ \'tb.rulenode.message\' | translate }}\n {{ \'tb.rulenode.metadata\' | translate }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{labelText:[{type:i}]}});class cn extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new Ne,this.sourceFieldSubcritption=[],this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({}),this.svListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required]],value:[e[n],[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.svListFormGroup.setControl("keyVals",this.fb.array(t));for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e);this.valueChangeSubscription=this.svListFormGroup.valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.updateModel()}))}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value)t.push(this.selectOptions.find((t=>t===e.key)));const n=[];for(const r of this.selectOptions)X(t.find((e=>e===r)))&&r!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.svListFormGroup.get("keyVals").removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){const e=this.svListFormGroup.get("keyVals");e.push(this.fb.group({key:["",[E.required]],value:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(e.controls[e.length-1])}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(Ce(this.destroy$)).subscribe((t=>{e.get("value").patchValue(this.targetKeyPrefix+t[0].toUpperCase()+t.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{kvMapRequired:!0}:this.svListFormGroup.valid?null:{kvFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cn,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:cn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",selectOptionsTranslate:"selectOptionsTranslate",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:V,useExisting:a((()=>cn)),multi:!0},{provide:w,useExisting:a((()=>cn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n \n {{ selectText }}\n \n \n {{selectOptionsTranslate.get(option) | translate}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n \n \n
\n
\n {{ hintText }}\n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),Me([h()],cn.prototype,"disabled",void 0),Me([h()],cn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:V,useExisting:a((()=>cn)),multi:!0},{provide:w,useExisting:a((()=>cn)),multi:!0}],template:'
\n
\n \n
\n
\n
\n \n {{ selectText }}\n \n \n {{selectOptionsTranslate.get(option) | translate}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n \n \n
\n
\n {{ hintText }}\n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],selectOptionsTranslate:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class fn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:fn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>fn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ve.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:V,useExisting:a((()=>fn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class gn{set enableFieldToggle(e){this._enableFieldToggle=pe(e)}get enableFieldToggle(){return this._enableFieldToggle}constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne,this.DataToFetch=ht}ngOnInit(){this.toggleControlGroup=this.fb.group({toggleControl:[null,[]]}),this.toggleControlGroup.get("toggleControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.toggleControlGroup.get("toggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("FetchToDataToggleComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:gn,selector:"tb-fetch-to-data-toggle",inputs:{enableFieldToggle:"enableFieldToggle"},providers:[{provide:V,useExisting:a((()=>gn)),multi:!0}],ngImport:t,template:'
\n \n {{ \'tb.rulenode.attributes\' | translate }}\n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n {{ \'tb.rulenode.fields\' | translate }}\n \n
\n',styles:[":host ::ng-deep{margin-bottom:12px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;width:215px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Re.MatButtonToggleGroup,selector:"mat-button-toggle-group",inputs:["appearance","name","vertical","value","multiple","disabled"],outputs:["valueChange","change"],exportAs:["matButtonToggleGroup"]},{kind:"component",type:Re.MatButtonToggle,selector:"mat-button-toggle",inputs:["disableRipple","aria-label","aria-labelledby","id","name","value","tabIndex","appearance","checked","disabled"],outputs:["change"],exportAs:["matButtonToggle"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-fetch-to-data-toggle",providers:[{provide:V,useExisting:a((()=>gn)),multi:!0}],template:'
\n \n {{ \'tb.rulenode.attributes\' | translate }}\n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n {{ \'tb.rulenode.fields\' | translate }}\n \n
\n',styles:[":host ::ng-deep{margin-bottom:12px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;width:215px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{enableFieldToggle:[{type:i}]}});class yn{constructor(e,t,n){this.store=e,this.translate=t,this.fb=n,this.destroy$=new Ne,this.separatorKeysCodes=[oe,ae,ie]}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[null,[]],sharedAttributeNames:[null,[]],serverAttributeNames:[null,[]],latestTsKeyNames:[null,[]],getLatestValueWithTs:[!1,[]]}),this.attributeControlGroup.valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.attributeControlGroup.patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}removeKey(e,t){const n=this.attributeControlGroup.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.attributeControlGroup.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.attributeControlGroup.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.attributeControlGroup.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}clearChipGrid(e){this.attributeControlGroup.get(e).patchValue([],{emitEvent:!0})}}e("SelectAttributesComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:yn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:V,useExisting:a((()=>yn)),multi:!0}],ngImport:t,template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin:10px 0 12px;display:block}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:V,useExisting:a((()=>yn)),multi:!0}],template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin:10px 0 12px;display:block}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class xn{}e("RulenodeCoreConfigCommonModule",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),xn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:xn,declarations:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn],imports:[H,L,qe],exports:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn]}),xn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,imports:[H,L,qe]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,decorators:[{type:l,args:[{declarations:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn],imports:[H,L,qe],exports:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn]}]}]});class bn{}e("RuleNodeCoreConfigActionModule",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),bn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:bn,declarations:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn],imports:[H,L,qe,xn],exports:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn]}),bn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,imports:[H,L,qe,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,decorators:[{type:l,args:[{declarations:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn],imports:[H,L,qe,xn],exports:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn]}]}]});class hn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[E.min(0),E.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:X(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:X(e?.outputValueKey)?e.outputValueKey:null,useCache:!X(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!X(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:X(e?.periodValueKey)?e.periodValueKey:null,round:X(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!X(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return e.inputValueKey=e.inputValueKey.trim(),e.outputValueKey=e.outputValueKey.trim(),e}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([E.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:hn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Cn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n].trim();return e.dataMapping=t,e}prepareInputConfig(e){let t,n;return t=X(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Cn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class vn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[E.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return Z(e)&&(e.attributesControl={clientAttributeNames:X(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:X(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:X(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!X(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:X(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!X(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:vn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ln,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:yn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Fn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.entityDetailsTranslationsMap=gt,this.entityDetailsList=[],this.searchText="",this.displayDetailsFn=this.displayDetails.bind(this);for(const e of Object.keys(dt))this.entityDetailsList.push(dt[e]);this.detailsFormControl=new P(""),this.filteredEntityDetails=this.detailsFormControl.valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchEntityDetails(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return this.searchText="",this.detailsFormControl.patchValue("",{emitEvent:!0}),this.detailsList=e?e.detailsList:[],t=X(e?.addToMetadata)?e.addToMetadata?Dt.METADATA:Dt.DATA:e?.fetchTo?e.fetchTo:Dt.DATA,{detailsList:X(e?.detailsList)?e.detailsList:null,fetchTo:t}}prepareOutputConfig(e){return e.detailsList=this.detailsList,e}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[E.required]],fetchTo:[e.fetchTo,[]]}),this.detailsList=e?e.detailsList:[]}displayDetails(e){return e?this.translate.instant(gt.get(e)):void 0}fetchEntityDetails(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(this.entityDetailsList.filter((t=>this.translate.instant(gt.get(dt[t])).toUpperCase().includes(e))))}return Ie(this.entityDetailsList)}detailsFieldSelected(e){this.addDetailsField(e.option.value),this.clear("")}removeDetailsField(e){const t=this.detailsList.indexOf(e);t>=0&&(this.detailsList.splice(t,1),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}addDetailsField(e){this.detailsList||(this.detailsList=[]);-1===this.detailsList.indexOf(e)&&(this.detailsList.push(e),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}onEntityDetailsInputFocus(){this.detailsFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clearChipGrid(){this.detailsList=[],this.entityDetailsConfigForm.get("detailsList").patchValue([],{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}clear(e=""){this.detailsInput.nativeElement.value=e,this.detailsFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}}e("EntityDetailsConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Fn,selector:"tb-enrichment-node-entity-details-config",viewQueries:[{propertyName:"detailsInput",first:!0,predicate:["detailsInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]},propDecorators:{detailsInput:[{type:o,args:["detailsInput",{static:!1}]}]}});class Ln extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[oe,ae,ie],this.aggregationTypes=k,this.aggregations=Object.keys(k),this.aggregationTypesTranslations=T,this.fetchMode=yt,this.fetchModes=Object.keys(yt),this.deduplicationStrategiesTranslations=xt,this.samplingOrders=Object.keys(bt),this.samplingOrdersTranslate=Ct,this.timeUnits=Object.values(st),this.timeUnitsTranslationMap=mt,this.timeUnitMap={[st.MILLISECONDS]:1,[st.SECONDS]:1e3,[st.MINUTES]:6e4,[st.HOURS]:36e5,[st.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[]],aggregation:[e.aggregation,[E.required]],fetchMode:[e.fetchMode,[E.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,e.startIntervalPattern=e.startIntervalPattern.trim(),e.endIntervalPattern=e.endIntervalPattern.trim(),delete e.interval,e}prepareInputConfig(e){return Z(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:X(e?.aggregation)?e.aggregation:k.NONE,fetchMode:X(e?.fetchMode)?e.fetchMode:yt.FIRST,orderBy:X(e?.orderBy)?e.orderBy:bt.ASC,limit:X(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!X(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:X(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:X(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:st.MINUTES,endInterval:X(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:X(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:st.MINUTES},startIntervalPattern:X(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:X(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===yt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([E.required,E.min(2),E.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([E.required,E.min(1),E.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([E.required,E.min(1),E.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}fetchModeHintSelector(){let e;switch(this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value){case yt.ALL:e="tb.rulenode.all-mode-hint";break;case yt.LAST:e="tb.rulenode.last-mode-hint";break;case yt.FIRST:e="tb.rulenode.first-mode-hint"}return e}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}}e("GetTelemetryFromDatabaseConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ln,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ln,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n {{ deduplicationStrategiesTranslations.get(fetchMode) | translate}}\n \n
\n {{ fetchModeHintSelector() | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle mat-button-toggle{width:215px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .additional-inputs{margin-bottom:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:Re.MatButtonToggleGroup,selector:"mat-button-toggle-group",inputs:["appearance","name","vertical","value","multiple","disabled"],outputs:["valueChange","change"],exportAs:["matButtonToggleGroup"]},{kind:"component",type:Re.MatButtonToggle,selector:"mat-button-toggle",inputs:["disableRipple","aria-label","aria-labelledby","id","name","value","tabIndex","appearance","checked","disabled"],outputs:["change"],exportAs:["matButtonToggle"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n {{ deduplicationStrategiesTranslations.get(fetchMode) | translate}}\n \n
\n {{ fetchModeHintSelector() | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle mat-button-toggle{width:215px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .additional-inputs{margin-bottom:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class kn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return Z(e)&&(e.attributesControl={clientAttributeNames:X(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:X(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:X(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!X(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA,tellFailureIfAbsent:!!X(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:X(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:kn,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:yn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorFields=[],this.originatorFieldsTranslations=ft;for(const e of Object.keys(ct))this.originatorFields.push(ct[e])}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){for(const t of Object.keys(e.dataMapping))e.dataMapping[t]=e.dataMapping[t].trim();return e}prepareInputConfig(e){return{dataMapping:X(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:X(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[E.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Tn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:cn,selector:"tb-sv-map-config",inputs:["selectOptions","selectOptionsTranslate","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class In extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht,this.originatorFieldsTranslations=ft,this.originatorFields=[],this.destroy$=new Ne,this.defaultKvMap={serialNumber:"sn"},this.defaultSvMap={name:"relatedEntityName",type:"relatedEntityType"},this.dataToFetchPrevValue="";for(const e of Object.keys(ct))this.originatorFields.push(ct[e])}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n].trim();return e.dataMapping=t,e}prepareInputConfig(e){let t;return X(e?.telemetry)?this.dataToFetchPrevValue=e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:this.dataToFetchPrevValue=X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,t=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{relationsQuery:X(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:this.dataToFetchPrevValue,dataMapping:t,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[E.required]],dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo,[]]}),this.relatedAttributesConfigForm.get("dataToFetch").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{e===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultSvMap,{emitEvent:!1}),e!==ht.FIELDS&&this.dataToFetchPrevValue===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultKvMap,{emitEvent:!1}),this.dataToFetchPrevValue=e}))}msgMetadataChipLabel(){switch(this.relatedAttributesConfigForm.get("dataToFetch").value){case ht.ATTRIBUTES:return"tb.rulenode.add-mapped-attribute-to";case ht.LATEST_TELEMETRY:return"tb.rulenode.add-mapped-latest-telemetry-to";case ht.FIELDS:return"tb.rulenode.add-mapped-fields-to"}}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("RelatedAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:In,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:In,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:mn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:cn,selector:"tb-sv-map-config",inputs:["selectOptions","selectOptionsTranslate","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Nn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=X(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Nn,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Sn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Sn,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class qn{}e("RulenodeCoreConfigEnrichmentModule",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),qn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:qn,declarations:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn],imports:[H,L,xn],exports:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn]}),qn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,decorators:[{type:l,args:[{declarations:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn],imports:[H,L,xn],exports:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn]}]}]});class Mn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Tt,this.azureIotHubCredentialsTypeTranslationsMap=It}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[E.required,E.min(1),E.max(200)]],clientId:[e?e.clientId:null,[E.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[E.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([E.required]);break;case"cert.PEM":t.get("privateKey").setValidators([E.required]),t.get("privateKeyFileName").setValidators([E.required]),t.get("cert").setValidators([E.required]),t.get("certFileName").setValidators([E.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Mn,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:O.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:O.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Se.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class An extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=St,this.ToByteStandartCharsetTypeTranslationMap=qt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[E.required]],retries:[e?e.retries:null,[E.min(0)]],batchSize:[e?e.batchSize:null,[E.min(0)]],linger:[e?e.linger:null,[E.min(0)]],bufferMemory:[e?e.bufferMemory:null,[E.min(0)]],acks:[e?e.acks:null,[E.required]],keySerializer:[e?e.keySerializer:null,[E.required]],valueSerializer:[e?e.valueSerializer:null,[E.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([E.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:An,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:An,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Gn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[]}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[E.required,E.min(1),E.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ee(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]}),this.subscriptions.push(this.mqttConfigForm.get("clientId").valueChanges.subscribe((e=>{ee(e)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1})})))}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}}e("MqttConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Gn,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:pn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRquired"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class En extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=I,this.entityType=x}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[E.required]],targets:[e?e.targets:[],[E.required]]})}}e("NotificationConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:En,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:En,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:Oe.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:He.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","disabled","notificationTypes"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Dn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[E.required]],topicName:[e?e.topicName:null,[E.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[E.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[E.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Dn,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Vn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[E.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[E.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Vn,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class wn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(Nt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[E.required]],requestMethod:[e?e.requestMethod:null,[E.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],trimDoubleQuotes:[!!e&&e.trimDoubleQuotes,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[E.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[E.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[E.required,E.min(1),E.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([E.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([E.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",wn),wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:wn,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:pn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRquired"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wn,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Pn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([E.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([E.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([E.required,E.min(1),E.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([E.required,E.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[E.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[E.required,E.min(1),E.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",Pn),Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Pn,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ke.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pn,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[E.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[E.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([E.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Rn,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Be.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class On extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(N),this.slackChanelTypesTranslateMap=S}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[E.required]],conversationType:[e?e.conversationType:null,[E.required]],conversation:[e?e.conversation:null,[E.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([E.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:On,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:On,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ze.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Hn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[E.required]],accessKeyId:[e?e.accessKeyId:null,[E.required]],secretAccessKey:[e?e.secretAccessKey:null,[E.required]],region:[e?e.region:null,[E.required]]})}}e("SnsConfigComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Hn,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Kn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=vt,this.sqsQueueTypes=Object.keys(vt),this.sqsQueueTypeTranslationsMap=Ft}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[E.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[E.required]],delaySeconds:[e?e.delaySeconds:null,[E.min(0),E.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[E.required]],secretAccessKey:[e?e.secretAccessKey:null,[E.required]],region:[e?e.region:null,[E.required]]})}}e("SqsConfigComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kn,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Bn{}e("RulenodeCoreConfigExternalModule",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Bn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Bn,declarations:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On],imports:[H,L,qe,xn],exports:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On]}),Bn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,imports:[H,L,qe,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,decorators:[{type:l,args:[{declarations:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On],imports:[H,L,qe,xn],exports:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On]}]}]});class Un extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.alarmStatusTranslationsMap=q,this.alarmStatusList=[],this.searchText="",this.displayStatusFn=this.displayStatus.bind(this);for(const e of Object.keys(M))this.alarmStatusList.push(M[e]);this.statusFormControl=new R(""),this.filteredAlarmStatus=this.statusFormControl.valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchAlarmStatus(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return this.searchText="",this.statusFormControl.patchValue("",{emitEvent:!0}),e}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e?e.alarmStatusList:null,[E.required]]})}displayStatus(e){return e?this.translate.instant(q.get(e)):void 0}fetchAlarmStatus(e){const t=this.getAlarmStatusList();if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(t.filter((t=>this.translate.instant(q.get(M[t])).toUpperCase().includes(e))))}return Ie(t)}alarmStatusSelected(e){this.addAlarmStatus(e.option.value),this.clear("")}removeAlarmStatus(e){const t=this.alarmStatusConfigForm.get("alarmStatusList").value;if(t){const n=t.indexOf(e);n>=0&&(t.splice(n,1),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}}addAlarmStatus(e){let t=this.alarmStatusConfigForm.get("alarmStatusList").value;t||(t=[]);-1===t.indexOf(e)&&(t.push(e),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}getAlarmStatusList(){return this.alarmStatusList.filter((e=>-1===this.alarmStatusConfigForm.get("alarmStatusList").value.indexOf(e)))}onAlarmStatusInputFocus(){this.statusFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.alarmStatusInput.nativeElement.value=e,this.statusFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.alarmStatusInput.nativeElement.blur(),this.alarmStatusInput.nativeElement.focus()}),0)}}e("CheckAlarmStatusComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Un,deps:[{token:A.Store},{token:_.TranslateService},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Un,selector:"tb-filter-node-check-alarm-status-config",viewQueries:[{propertyName:"alarmStatusInput",first:!0,predicate:["alarmStatusInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.UntypedFormBuilder}]},propDecorators:{alarmStatusInput:[{type:o,args:["alarmStatusInput",{static:!1}]}]}});class zn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.checkMessageConfigForm}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e?e.messageNames:null,[]],metadataNames:[e?e.metadataNames:null,[]],checkAllKeys:[!!e&&e.checkAllKeys,[]]})}validateConfig(){const e=this.checkMessageConfigForm.get("messageNames").value,t=this.checkMessageConfigForm.get("metadataNames").value;return e.length>0||t.length>0}removeMessageName(e){const t=this.checkMessageConfigForm.get("messageNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("messageNames").setValue(t,{emitEvent:!0}))}removeMetadataName(e){const t=this.checkMessageConfigForm.get("metadataNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("metadataNames").setValue(t,{emitEvent:!0}))}addMessageName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("messageNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("messageNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}addMetadataName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("metadataNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("metadataNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CheckMessageConfigComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zn,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class _n extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.keys(g),this.entitySearchDirectionTranslationsMap=y}configForm(){return this.checkRelationConfigForm}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[!!e&&e.checkForSingleEntity,[]],direction:[e?e.direction:null,[]],entityType:[e?e.entityType:null,e&&e.checkForSingleEntity?[E.required]:[]],entityId:[e?e.entityId:null,e&&e.checkForSingleEntity?[E.required]:[]],relationType:[e?e.relationType:null,[E.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[E.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[E.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_n,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_n,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:_e.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Ee.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","required","disabled","subscriptSizing"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class jn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=it,this.perimeterTypes=Object.keys(it),this.perimeterTypeTranslationMap=lt,this.rangeUnits=Object.keys(ut),this.rangeUnitTranslationMap=pt}configForm(){return this.geoFilterConfigForm}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[E.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[E.required]],perimeterType:[e?e.perimeterType:null,[E.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([E.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==it.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([])):(this.geoFilterConfigForm.get("centerLatitude").setValidators([E.required,E.min(-90),E.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([E.required,E.min(-180),E.max(180)]),this.geoFilterConfigForm.get("range").setValidators([E.required,E.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([E.required])),t||n!==it.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([E.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jn,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class $n extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e?e.messageTypes:null,[E.required]]})}}e("MessageTypeConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$n,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$n,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:un,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.TENANT,x.CUSTOMER,x.USER,x.DASHBOARD,x.RULE_CHAIN,x.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e?e.originatorTypes:null,[E.required]]})}}e("OriginatorTypeConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qn,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n
\n',dependencies:[{kind:"component",type:je.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","disabled","subscriptSizing","allowedEntityTypes","ignoreAuthorityFilter"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Jn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jn,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Yn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.switchConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",r=this.switchConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.switchConfigForm.get(t).setValue(e)}))}onValidate(){this.switchConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yn,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Wn{}e("RuleNodeCoreConfigFilterModule",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Wn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Wn,declarations:[zn,_n,jn,$n,Qn,Jn,Yn,Un],imports:[H,L,xn],exports:[zn,_n,jn,$n,Qn,Jn,Yn,Un]}),Wn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,decorators:[{type:l,args:[{declarations:[zn,_n,jn,$n,Qn,Jn,Yn,Un],imports:[H,L,xn],exports:[zn,_n,jn,$n,Qn,Jn,Yn,Un]}]}]});class Xn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=ot,this.originatorSources=Object.keys(ot),this.originatorSourceTranslationMap=at,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.USER,x.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[E.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===ot.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([E.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===ot.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([E.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xn,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fn,selector:"tb-relations-query-config-old",inputs:["disabled","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Zn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[E.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Zn,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",value:"false"},{name:"tb.mail-body-type.html",value:"true"},{name:"tb.mail-body-type.dynamic",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[E.required]],toTemplate:[e?e.toTemplate:null,[E.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[E.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null],bodyTemplate:[e?e.bodyTemplate:null,[E.required]]}),this.toEmailConfigForm.get("mailBodyType").valueChanges.pipe(ve([e?.subjectTemplate])).subscribe((e=>{"dynamic"===e?(this.toEmailConfigForm.get("isHtmlTemplate").patchValue("",{emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").setValidators(E.required)):this.toEmailConfigForm.get("isHtmlTemplate").clearValidators(),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity()}))}}e("ToEmailConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:er,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],keys:[e?e.keys:null,[E.required]]})}configForm(){return this.copyKeysConfigForm}removeKey(e){const t=this.copyKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.copyKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.copyKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.copyKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CopyKeysConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[E.required]]})}}e("RenameKeysConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[E.required]]})}}e("NodeJsonPathConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n",dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n"}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],keys:[e?e.keys:null,[E.required]]})}configForm(){return this.deleteKeysConfigForm}removeKey(e){const t=this.deleteKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteKeysConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class ar{}e("RulenodeCoreConfigTransformModule",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ar.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:ar,declarations:[Xn,Zn,er,tr,nr,rr,or],imports:[H,L,xn],exports:[Xn,Zn,er,tr,nr,rr,or]}),ar.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,decorators:[{type:l,args:[{declarations:[Xn,Zn,er,tr,nr,rr,or],imports:[H,L,xn],exports:[Xn,Zn,er,tr,nr,rr,or]}]}]});class ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=x}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[E.required]]})}}e("RuleChainInputComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ir,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:_e.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class lr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:lr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class sr{}e("RuleNodeCoreConfigFlowModule",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),sr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:sr,declarations:[ir,lr],imports:[H,L,xn],exports:[ir,lr]}),sr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,decorators:[{type:l,args:[{declarations:[ir,lr],imports:[H,L,xn],exports:[ir,lr]}]}]});class mr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{"create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","output-message-type":"Output message type","output-message-type-required":"Output message type is required","output-message-type-max-length":"Output message type should be less than 256","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. In case you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required!","limit-range":"Limit should be in a range from 2 to 1000!","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Time value should be in a range from 1 to 2147483647!","start-interval-value-required":"Start interval value is required!","end-interval-value-required":"End interval value is required!",filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Notify device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-hint":"If the message arrives from the device, we will push it back to the device by default.","notify-device-delete-hint":"Send notification about deleted attributes to device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","add-timeseries-key":"Add timeseries key","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Hint: use regular expression to copy keys by pattern",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","key-name":"Key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Max relation level should be greater than 0 or unspecified!","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required!","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required!","target-key":"Target key","target-key-required":"Target key is required!","attr-mapping-required":"At least one mapping entry should be specified!","fields-mapping":"Fields mapping*","fields-mapping-required":"At least one field mapping should be specified.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","source-field":"Source field","source-field-required":"Source field is required!","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","body-template":"Body Template","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","trim-double-quotes":"Message without quotes","trim-double-quotes-hint":"If selected, request body message payload will be sent without double quotes, i.e. msg = message body","read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Hint: Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Hint: Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Hint: Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required!","end-interval-required":"Interval end is required!","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"entity-details":"Select entity details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","entity-details-list-empty":"No entity details selected!","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-key-name":"Latitude key name","longitude-key-name":"Longitude key name","latitude-key-name-required":"Latitude key name is required.","longitude-key-name-required":"Longitude key name is required.","fetch-perimeter-info-from-message-metadata":"Fetch perimeter information from message metadata","perimeter-key-name":"Perimeter key name","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Please, use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required!","output-value-key":"Output value key","output-value-key-required":"Output value key is required!","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15!","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-cashing":"Use cashing","use-cashing-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required!","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time series","message-body-type":"Message body","message-metadata-type":"Message metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-type-field-input":"Type","argument-type-field-input-required":"Argument type is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Hint: use 0 to convert result to integer","add-to-body-field-input":"Add to message body","add-to-metadata-field-input":"Add to message metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Hint: specify a mathematical expression to evaluate. For example, transform Fahrenheit to Celsius using (x - 32) / 1.8)","retained-message":"Retained","attributes-mapping":"Attributes mapping*","latest-telemetry-mapping":"Latest telemetry mapping*","add-mapped-attribute-to":"Add mapped attributes to:","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to:","add-mapped-fields-to":"Add mapped fields to:","add-selected-details-to":"Add selected details to:","clear-selected-details":"Clear selected details","clear-selected-keys":"Clear selected keys","fetch-credentials-to":"Fetch credentials to:","add-originator-attributes-to":"Add originator attributes to:","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound message metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell Failure","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to:",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output message metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end")!',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch:","mapping-of-customers":"Mapping of customer's:",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to:","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's:","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required"},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping entry","add-entry":"Add entry","unique-key-value-pair-error":"'{{valText}}' must be different from the current '{{keyText}}'"},"mail-body-type":{"plain-text":"Plain Text",html:"HTML",dynamic:"Dynamic"}}},!0)}(e)}}e("RuleNodeCoreConfigModule",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,deps:[{token:_.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),mr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:mr,declarations:[$e],imports:[H,L],exports:[bn,Wn,qn,Bn,ar,sr,$e]}),mr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,imports:[H,L,bn,Wn,qn,Bn,ar,sr]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,decorators:[{type:l,args:[{declarations:[$e],imports:[H,L],exports:[bn,Wn,qn,Bn,ar,sr,$e]}]}],ctorParameters:function(){return[{type:_.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map From d6ec789cb50e519986b97d25f963d6201cdfdb3a Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 1 Jun 2023 12:27:20 +0300 Subject: [PATCH 106/207] add java doc for upgrade method in TbVersionedNode interface --- .../thingsboard/rule/engine/api/TbVersionedNode.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java index be9a5d01e2..95b93fa222 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbVersionedNode.java @@ -20,6 +20,16 @@ import org.thingsboard.server.common.data.util.TbPair; public interface TbVersionedNode extends TbNode { + /** + * Upgrades the configuration from a specific version to the current version specified in the + * {@link RuleNode} annotation for the instance of {@link TbVersionedNode}. + * + * @param fromVersion The version from which the configuration needs to be upgraded. + * @param oldConfiguration The old configuration to be upgraded. + * @return A pair consisting of a Boolean flag indicating the success of the upgrade + * and a JsonNode representing the upgraded configuration. + * @throws TbNodeException If an error occurs during the upgrade process. + */ TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException; } From c2a87aba6097028553bc35857f825bff252ba09a Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Thu, 1 Jun 2023 14:47:47 +0300 Subject: [PATCH 107/207] Add redis-sentinel mode support --- .../src/main/resources/thingsboard.yml | 12 +- .../cache/TBRedisCacheConfiguration.java | 23 ++++ .../cache/TBRedisClusterConfiguration.java | 26 +--- .../cache/TBRedisSentinelConfiguration.java | 62 +++++++++ docker/.env | 2 +- docker/.gitignore | 3 + docker/README.md | 3 +- docker/cache-redis-sentinel.env | 7 ++ docker/compose-utils.sh | 19 ++- .../docker-compose.redis-sentinel.volumes.yml | 40 ++++++ docker/docker-compose.redis-sentinel.yml | 119 ++++++++++++++++++ msa/black-box-tests/README.md | 4 + .../server/msa/ContainerTestSuite.java | 29 ++++- .../server/msa/ThingsBoardDbInstaller.java | 58 +++++++-- .../src/main/resources/tb-coap-transport.yml | 12 +- .../src/main/resources/tb-http-transport.yml | 12 +- .../src/main/resources/tb-lwm2m-transport.yml | 12 +- .../src/main/resources/tb-mqtt-transport.yml | 12 +- .../src/main/resources/tb-snmp-transport.yml | 12 +- 19 files changed, 417 insertions(+), 50 deletions(-) create mode 100644 common/cache/src/main/java/org/thingsboard/server/cache/TBRedisSentinelConfiguration.java create mode 100644 docker/cache-redis-sentinel.env create mode 100644 docker/docker-compose.redis-sentinel.volumes.yml create mode 100644 docker/docker-compose.redis-sentinel.yml diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index fa7565b048..2525956d35 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -502,7 +502,7 @@ cache: spring.data.redis.repositories.enabled: false redis: - # standalone or cluster + # standalone or cluster or sentinel connection: type: "${REDIS_CONNECTION_TYPE:standalone}" standalone: @@ -522,6 +522,16 @@ redis: nodes: "${REDIS_NODES:}" # Maximum number of redirects to follow when executing commands across the cluster. max-redirects: "${REDIS_MAX_REDIRECTS:12}" + # if set false will be used pool config build from values of the pool config section + useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" + sentinel: + # name of master node + master: "${REDIS_MASTER:}" + # comma-separated list of "host:port" pairs of sentinels + sentinels: "${REDIS_SENTINELS:}" + # password to authenticate with sentinel + password: "${REDIS_SENTINEL_PASSWORD:}" + # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" # db index db: "${REDIS_DB:0}" diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisCacheConfiguration.java b/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisCacheConfiguration.java index 9c4c962dc2..36f3dddc3d 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisCacheConfiguration.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisCacheConfiguration.java @@ -26,14 +26,19 @@ import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.util.Assert; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.EntityId; import redis.clients.jedis.JedisPoolConfig; import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; @Configuration @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @@ -41,6 +46,9 @@ import java.time.Duration; @Data public abstract class TBRedisCacheConfiguration { + private static final String COMMA = ","; + private static final String COLON = ":"; + @Value("${redis.evictTtlInMs:60000}") private int evictTtlInMs; @@ -126,4 +134,19 @@ public abstract class TBRedisCacheConfiguration { poolConfig.setBlockWhenExhausted(blockWhenExhausted); return poolConfig; } + + protected List getNodes(String nodes) { + List result; + if (StringUtils.isBlank(nodes)) { + result = Collections.emptyList(); + } else { + result = new ArrayList<>(); + for (String hostPort : nodes.split(COMMA)) { + String host = hostPort.split(COLON)[0]; + int port = Integer.parseInt(hostPort.split(COLON)[1]); + result.add(new RedisNode(host, port)); + } + } + return result; + } } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java b/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java index dfc6ebd225..0a378103b0 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisClusterConfiguration.java @@ -20,22 +20,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisClusterConfiguration; -import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; -import org.thingsboard.server.common.data.StringUtils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; @Configuration @ConditionalOnMissingBean(TbCaffeineCacheConfiguration.class) @ConditionalOnProperty(prefix = "redis.connection", value = "type", havingValue = "cluster") public class TBRedisClusterConfiguration extends TBRedisCacheConfiguration { - private static final String COMMA = ","; - private static final String COLON = ":"; - @Value("${redis.cluster.nodes:}") private String clusterNodes; @@ -59,19 +50,4 @@ public class TBRedisClusterConfiguration extends TBRedisCacheConfiguration { return new JedisConnectionFactory(clusterConfiguration, buildPoolConfig()); } } - - private List getNodes(String nodes) { - List result; - if (StringUtils.isBlank(nodes)) { - result = Collections.emptyList(); - } else { - result = new ArrayList<>(); - for (String hostPort : nodes.split(COMMA)) { - String host = hostPort.split(COLON)[0]; - Integer port = Integer.valueOf(hostPort.split(COLON)[1]); - result.add(new RedisNode(host, port)); - } - } - return result; - } -} \ No newline at end of file +} diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisSentinelConfiguration.java b/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisSentinelConfiguration.java new file mode 100644 index 0000000000..78cb445d82 --- /dev/null +++ b/common/cache/src/main/java/org/thingsboard/server/cache/TBRedisSentinelConfiguration.java @@ -0,0 +1,62 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.cache; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisSentinelConfiguration; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; + +@Configuration +@ConditionalOnMissingBean(TbCaffeineCacheConfiguration.class) +@ConditionalOnProperty(prefix = "redis.connection", value = "type", havingValue = "sentinel") +public class TBRedisSentinelConfiguration extends TBRedisCacheConfiguration { + + @Value("${redis.sentinel.master:}") + private String master; + + @Value("${redis.sentinel.sentinels:}") + private String sentinels; + + @Value("${redis.sentinel.password:}") + private String sentinelPassword; + + @Value("${redis.sentinel.useDefaultPoolConfig:true}") + private boolean useDefaultPoolConfig; + + @Value("${redis.db:}") + private Integer database; + + @Value("${redis.password:}") + private String password; + + public JedisConnectionFactory loadFactory() { + RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration(); + redisSentinelConfiguration.setMaster(master); + redisSentinelConfiguration.setSentinels(getNodes(sentinels)); + redisSentinelConfiguration.setSentinelPassword(sentinelPassword); + redisSentinelConfiguration.setPassword(password); + redisSentinelConfiguration.setDatabase(database); + if (useDefaultPoolConfig) { + return new JedisConnectionFactory(redisSentinelConfiguration); + } else { + return new JedisConnectionFactory(redisSentinelConfiguration, buildPoolConfig()); + } + } + +} diff --git a/docker/.env b/docker/.env index f33ed50da5..37c9768296 100644 --- a/docker/.env +++ b/docker/.env @@ -1,6 +1,6 @@ TB_QUEUE_TYPE=kafka -# redis or redis-cluster +# redis or redis-cluster or redis-sentinel CACHE=redis DOCKER_REPO=thingsboard diff --git a/docker/.gitignore b/docker/.gitignore index c9172ae6ce..b6c9fcf18c 100644 --- a/docker/.gitignore +++ b/docker/.gitignore @@ -12,6 +12,9 @@ tb-node/redis-cluster-data-2/** tb-node/redis-cluster-data-3/** tb-node/redis-cluster-data-4/** tb-node/redis-cluster-data-5/** +tb-node/redis-sentinel-data-master/** +tb-node/redis-sentinel-data-slave/** +tb-node/redis-sentinel-data-sentinel/** tb-node/redis-data/** !.env diff --git a/docker/README.md b/docker/README.md index 71ea87f353..437e583a99 100644 --- a/docker/README.md +++ b/docker/README.md @@ -21,8 +21,9 @@ In order to set cache type change the value of `CACHE` variable in `.env` file t - `redis` - use Redis standalone cache (1 node - 1 master); - `redis-cluster` - use Redis cluster cache (6 nodes - 3 masters, 3 slaves); +- `redis-sentinel` - use Redis cluster in a sentinel mode (3 nodes - 1 master, 1 slave, 1 sentinel) -**NOTE**: According to the cache type corresponding docker service will be deployed (see `docker-compose.redis.yml`, `docker-compose.redis-cluster.yml` for details). +**NOTE**: According to the cache type corresponding docker service will be deployed (see `docker-compose.redis.yml`, `docker-compose.redis-cluster.yml`, `docker-compose.redis-sentinel.yml` for details). Execute the following command to create log folders for the services and chown of these folders to the docker container users. To be able to change user, **chown** command is used, which requires sudo permissions (script will request password for a sudo access): diff --git a/docker/cache-redis-sentinel.env b/docker/cache-redis-sentinel.env new file mode 100644 index 0000000000..39a1246d9c --- /dev/null +++ b/docker/cache-redis-sentinel.env @@ -0,0 +1,7 @@ +CACHE_TYPE=redis +REDIS_CONNECTION_TYPE=sentinel +REDIS_MASTER=mymaster +REDIS_SENTINELS=redis-sentinel:26379 +REDIS_SENTINEL_PASSWORD=sentinel +REDIS_USE_DEFAULT_POOL_CONFIG=false +REDIS_PASSWORD=thingsboard diff --git a/docker/compose-utils.sh b/docker/compose-utils.sh index 49f3e20e27..19ca342b9b 100755 --- a/docker/compose-utils.sh +++ b/docker/compose-utils.sh @@ -84,8 +84,11 @@ function additionalComposeCacheArgs() { redis-cluster) CACHE_COMPOSE_ARGS="-f docker-compose.redis-cluster.yml" ;; + redis-sentinel) + CACHE_COMPOSE_ARGS="-f docker-compose.redis-sentinel.yml" + ;; *) - echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster'." >&2 + echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster' or 'redis-sentinel'." >&2 exit 1 esac echo $CACHE_COMPOSE_ARGS @@ -114,8 +117,11 @@ function additionalStartupServices() { redis-cluster) ADDITIONAL_STARTUP_SERVICES="$ADDITIONAL_STARTUP_SERVICES redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5" ;; + redis-sentinel) + ADDITIONAL_STARTUP_SERVICES="$ADDITIONAL_STARTUP_SERVICES redis-master redis-slave redis-sentinel" + ;; *) - echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster'." >&2 + echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster' or 'redis-sentinel'." >&2 exit 1 esac @@ -160,8 +166,15 @@ function permissionList() { 1001 1001 tb-node/redis-cluster-data-5 " ;; + redis-sentinel) + PERMISSION_LIST="$PERMISSION_LIST + 1001 1001 tb-node/redis-sentinel-data-master + 1001 1001 tb-node/redis-sentinel-data-slave + 1001 1001 tb-node/redis-sentinel-data-sentinel + " + ;; *) - echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster'." >&2 + echo "Unknown CACHE value specified in the .env file: '${CACHE}'. Should be either 'redis' or 'redis-cluster' or 'redis-sentinel'." >&2 exit 1 esac diff --git a/docker/docker-compose.redis-sentinel.volumes.yml b/docker/docker-compose.redis-sentinel.volumes.yml new file mode 100644 index 0000000000..38534368ea --- /dev/null +++ b/docker/docker-compose.redis-sentinel.volumes.yml @@ -0,0 +1,40 @@ +# +# Copyright © 2016-2023 The Thingsboard Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +version: '3.0' + +services: + # Redis sentinel + redis-master: + volumes: + - redis-sentinel-data-master:/bitnami/redis/data + redis-slave: + volumes: + - redis-sentinel-data-slave:/bitnami/redis/data + redis-sentinel: + volumes: + - redis-sentinel-data-sentinel:/bitnami/redis/data + +volumes: + redis-sentinel-data-master: + external: + name: ${REDIS_SENTINEL_DATA_VOLUME_MASTER} + redis-sentinel-data-slave: + external: + name: ${REDIS_SENTINEL_DATA_VOLUME_SLAVE} + redis-sentinel-data-sentinel: + external: + name: ${REDIS_SENTINEL_DATA_VOLUME_SENTINEL} diff --git a/docker/docker-compose.redis-sentinel.yml b/docker/docker-compose.redis-sentinel.yml new file mode 100644 index 0000000000..32b3f1e826 --- /dev/null +++ b/docker/docker-compose.redis-sentinel.yml @@ -0,0 +1,119 @@ +# +# Copyright © 2016-2023 The Thingsboard Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +version: '3.0' + +services: + # Redis sentinel + redis-master: + image: 'bitnami/redis:7.0' + volumes: + - ./tb-node/redis-sentinel-data-master:/bitnami/redis/data + environment: + - 'REDIS_REPLICATION_MODE=master' + - 'REDIS_PASSWORD=thingsboard' + + redis-slave: + image: 'bitnami/redis:7.0' + volumes: + - ./tb-node/redis-sentinel-data-slave:/bitnami/redis/data + environment: + - 'REDIS_REPLICATION_MODE=slave' + - 'REDIS_MASTER_HOST=redis-master' + - 'REDIS_MASTER_PASSWORD=thingsboard' + - 'REDIS_PASSWORD=thingsboard' + depends_on: + - redis-master + + redis-sentinel: + image: 'bitnami/redis-sentinel:7.0' + volumes: + - ./tb-node/redis-sentinel-data-sentinel:/bitnami/redis/data + environment: + - 'REDIS_MASTER_HOST=redis-master' + - 'REDIS_MASTER_SET=mymaster' + - 'REDIS_SENTINEL_PASSWORD=sentinel' + - 'REDIS_MASTER_PASSWORD=thingsboard' + depends_on: + - redis-master + - redis-slave + + # ThingsBoard setup to use redis-sentinel + tb-core1: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-core2: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-rule-engine1: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-rule-engine2: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-mqtt-transport1: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-mqtt-transport2: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-http-transport1: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-http-transport2: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-coap-transport: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-lwm2m-transport: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-snmp-transport: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-vc-executor1: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel + tb-vc-executor2: + env_file: + - cache-redis-sentinel.env + depends_on: + - redis-sentinel diff --git a/msa/black-box-tests/README.md b/msa/black-box-tests/README.md index 4a88d5e8cd..340f0d0eb8 100644 --- a/msa/black-box-tests/README.md +++ b/msa/black-box-tests/README.md @@ -26,6 +26,10 @@ As result, in REPOSITORY column, next images should be present: mvn clean install -DblackBoxTests.skip=false -DblackBoxTests.redisCluster=true +- Run the black box tests in the [msa/black-box-tests](../black-box-tests) directory with Redis sentinel: + + mvn clean install -DblackBoxTests.skip=false -DblackBoxTests.redisSentinel=true + - Run the black box tests in the [msa/black-box-tests](../black-box-tests) directory in Hybrid mode (postgres + cassandra): mvn clean install -DblackBoxTests.skip=false -DblackBoxTests.hybridMode=true diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java index ffbe14ed52..c6be6ec271 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java @@ -43,6 +43,7 @@ import static org.testng.Assert.fail; @Slf4j public class ContainerTestSuite { final static boolean IS_REDIS_CLUSTER = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisCluster")); + final static boolean IS_REDIS_SENTINEL = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisSentinel")); final static boolean IS_HYBRID_MODE = Boolean.parseBoolean(System.getProperty("blackBoxTests.hybridMode")); final static String QUEUE_TYPE = System.getProperty("blackBoxTests.queue", "kafka"); private static final String SOURCE_DIR = "./../../docker/"; @@ -80,8 +81,9 @@ public class ContainerTestSuite { installTb = new ThingsBoardDbInstaller(); installTb.createVolumes(); log.info("System property of blackBoxTests.redisCluster is {}", IS_REDIS_CLUSTER); + log.info("System property of blackBoxTests.redisSentinel is {}", IS_REDIS_SENTINEL); log.info("System property of blackBoxTests.hybridMode is {}", IS_HYBRID_MODE); - boolean skipTailChildContainers = Boolean.valueOf(System.getProperty("blackBoxTests.skipTailChildContainers")); + boolean skipTailChildContainers = Boolean.parseBoolean(System.getProperty("blackBoxTests.skipTailChildContainers")); try { final String targetDir = FileUtils.getTempDirectoryPath() + "/" + "ContainerTestSuite-" + UUID.randomUUID() + "/"; log.info("targetDir {}", targetDir); @@ -109,8 +111,8 @@ public class ContainerTestSuite { new File(targetDir + (IS_HYBRID_MODE ? "docker-compose.hybrid-test-extras.yml" : "docker-compose.postgres-test-extras.yml")), new File(targetDir + "docker-compose.postgres.volumes.yml"), new File(targetDir + "docker-compose." + QUEUE_TYPE + ".yml"), - new File(targetDir + (IS_REDIS_CLUSTER ? "docker-compose.redis-cluster.yml" : "docker-compose.redis.yml")), - new File(targetDir + (IS_REDIS_CLUSTER ? "docker-compose.redis-cluster.volumes.yml" : "docker-compose.redis.volumes.yml")), + new File(targetDir + resolveComposeFile()), + new File(targetDir + resolveComposeVolumesFile()), new File(targetDir + ("docker-selenium.yml")) )); @@ -175,6 +177,27 @@ public class ContainerTestSuite { fail("Failed to create test container"); } } + + private static String resolveComposeFile() { + if (IS_REDIS_CLUSTER) { + return "docker-compose.redis-cluster.yml"; + } + if (IS_REDIS_SENTINEL) { + return "docker-compose.redis-sentinel.yml"; + } + return "docker-compose.redis.yml"; + } + + private static String resolveComposeVolumesFile() { + if (IS_REDIS_CLUSTER) { + return "docker-compose.redis-cluster.volumes.yml"; + } + if (IS_REDIS_SENTINEL) { + return "docker-compose.redis-sentinel.volumes.yml"; + } + return "docker-compose.redis.volumes.yml"; + } + public void stop() { if (isActive) { testContainer.stop(); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java index e6c9856094..40f9758f33 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java @@ -32,12 +32,14 @@ import java.util.stream.IntStream; public class ThingsBoardDbInstaller { final static boolean IS_REDIS_CLUSTER = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisCluster")); + final static boolean IS_REDIS_SENTINEL = Boolean.parseBoolean(System.getProperty("blackBoxTests.redisSentinel")); final static boolean IS_HYBRID_MODE = Boolean.parseBoolean(System.getProperty("blackBoxTests.hybridMode")); private final static String POSTGRES_DATA_VOLUME = "tb-postgres-test-data-volume"; private final static String CASSANDRA_DATA_VOLUME = "tb-cassandra-test-data-volume"; private final static String REDIS_DATA_VOLUME = "tb-redis-data-volume"; private final static String REDIS_CLUSTER_DATA_VOLUME = "tb-redis-cluster-data-volume"; + private final static String REDIS_SENTINEL_DATA_VOLUME = "tb-redis-sentinel-data-volume"; private final static String TB_LOG_VOLUME = "tb-log-test-volume"; private final static String TB_COAP_TRANSPORT_LOG_VOLUME = "tb-coap-transport-log-test-volume"; private final static String TB_LWM2M_TRANSPORT_LOG_VOLUME = "tb-lwm2m-transport-log-test-volume"; @@ -54,6 +56,7 @@ public class ThingsBoardDbInstaller { private final String redisDataVolume; private final String redisClusterDataVolume; + private final String redisSentinelDataVolume; private final String tbLogVolume; private final String tbCoapTransportLogVolume; private final String tbLwm2mTransportLogVolume; @@ -73,12 +76,8 @@ public class ThingsBoardDbInstaller { ? new File("./../../docker/docker-compose.hybrid.yml") : new File("./../../docker/docker-compose.postgres.yml"), new File("./../../docker/docker-compose.postgres.volumes.yml"), - IS_REDIS_CLUSTER - ? new File("./../../docker/docker-compose.redis-cluster.yml") - : new File("./../../docker/docker-compose.redis.yml"), - IS_REDIS_CLUSTER - ? new File("./../../docker/docker-compose.redis-cluster.volumes.yml") - : new File("./../../docker/docker-compose.redis.volumes.yml") + resolveComposeFile(), + resolveComposeVolumesFile() )); if (IS_HYBRID_MODE) { composeFiles.add(new File("./../../docker/docker-compose.cassandra.volumes.yml")); @@ -94,6 +93,7 @@ public class ThingsBoardDbInstaller { cassandraDataVolume = project + "_" + CASSANDRA_DATA_VOLUME; redisDataVolume = project + "_" + REDIS_DATA_VOLUME; redisClusterDataVolume = project + "_" + REDIS_CLUSTER_DATA_VOLUME; + redisSentinelDataVolume = project + "_" + REDIS_SENTINEL_DATA_VOLUME; tbLogVolume = project + "_" + TB_LOG_VOLUME; tbCoapTransportLogVolume = project + "_" + TB_COAP_TRANSPORT_LOG_VOLUME; tbLwm2mTransportLogVolume = project + "_" + TB_LWM2M_TRANSPORT_LOG_VOLUME; @@ -121,12 +121,36 @@ public class ThingsBoardDbInstaller { for (int i = 0; i < 6; i++) { env.put("REDIS_CLUSTER_DATA_VOLUME_" + i, redisClusterDataVolume + '-' + i); } + } else if (IS_REDIS_SENTINEL) { + env.put("REDIS_SENTINEL_DATA_VOLUME_MASTER", redisSentinelDataVolume + "-" + "master"); + env.put("REDIS_SENTINEL_DATA_VOLUME_SLAVE", redisSentinelDataVolume + "-" + "slave"); + env.put("REDIS_SENTINEL_DATA_VOLUME_SENTINEL", redisSentinelDataVolume + "-" + "sentinel"); } else { env.put("REDIS_DATA_VOLUME", redisDataVolume); } dockerCompose.withEnv(env); } + private static File resolveComposeVolumesFile() { + if (IS_REDIS_CLUSTER) { + return new File("./../../docker/docker-compose.redis-cluster.volumes.yml"); + } + if (IS_REDIS_SENTINEL) { + return new File("./../../docker/docker-compose.redis-sentinel.volumes.yml"); + } + return new File("./../../docker/docker-compose.redis.volumes.yml"); + } + + private static File resolveComposeFile() { + if (IS_REDIS_CLUSTER) { + return new File("./../../docker/docker-compose.redis-cluster.yml"); + } + if (IS_REDIS_SENTINEL) { + return new File("./../../docker/docker-compose.redis-sentinel.yml"); + } + return new File("./../../docker/docker-compose.redis.yml"); + } + public Map getEnv() { return env; } @@ -163,18 +187,30 @@ public class ThingsBoardDbInstaller { dockerCompose.withCommand("volume create " + tbVcExecutorLogVolume); dockerCompose.invokeDocker(); - String additionalServices = ""; + StringBuilder additionalServices = new StringBuilder(); if (IS_HYBRID_MODE) { - additionalServices += " cassandra"; + additionalServices.append(" cassandra"); } if (IS_REDIS_CLUSTER) { for (int i = 0; i < 6; i++) { - additionalServices = additionalServices + " redis-node-" + i; + additionalServices.append(" redis-node-").append(i); dockerCompose.withCommand("volume create " + redisClusterDataVolume + '-' + i); dockerCompose.invokeDocker(); } + } else if (IS_REDIS_SENTINEL) { + additionalServices.append(" redis-master"); + dockerCompose.withCommand("volume create " + redisSentinelDataVolume +"-" + "master"); + dockerCompose.invokeDocker(); + + additionalServices.append(" redis-slave"); + dockerCompose.withCommand("volume create " + redisSentinelDataVolume + '-' + "slave"); + dockerCompose.invokeDocker(); + + additionalServices.append(" redis-sentinel"); + dockerCompose.withCommand("volume create " + redisSentinelDataVolume + '-' + "sentinel"); + dockerCompose.invokeDocker(); } else { - additionalServices += " redis"; + additionalServices.append(" redis"); dockerCompose.withCommand("volume create " + redisDataVolume); dockerCompose.invokeDocker(); } @@ -189,7 +225,7 @@ public class ThingsBoardDbInstaller { try { dockerCompose.withCommand("down -v"); dockerCompose.invokeCompose(); - } catch (Exception e) {} + } catch (Exception ignored) {} } } diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 7ea553fe5c..332709e3fa 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -46,7 +46,7 @@ cache: type: "${CACHE_TYPE:redis}" redis: - # standalone or cluster + # standalone or cluster or sentinel connection: type: "${REDIS_CONNECTION_TYPE:standalone}" standalone: @@ -66,6 +66,16 @@ redis: nodes: "${REDIS_NODES:}" # Maximum number of redirects to follow when executing commands across the cluster. max-redirects: "${REDIS_MAX_REDIRECTS:12}" + # if set false will be used pool config build from values of the pool config section + useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" + sentinel: + # name of master node + master: "${REDIS_MASTER:}" + # comma-separated list of "host:port" pairs of sentinels + sentinels: "${REDIS_SENTINELS:}" + # password to authenticate with sentinel + password: "${REDIS_SENTINEL_PASSWORD:}" + # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" # db index db: "${REDIS_DB:0}" diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index 346ec48eae..c8a45c161b 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -73,7 +73,7 @@ cache: type: "${CACHE_TYPE:redis}" redis: - # standalone or cluster + # standalone or cluster or sentinel connection: type: "${REDIS_CONNECTION_TYPE:standalone}" standalone: @@ -93,6 +93,16 @@ redis: nodes: "${REDIS_NODES:}" # Maximum number of redirects to follow when executing commands across the cluster. max-redirects: "${REDIS_MAX_REDIRECTS:12}" + # if set false will be used pool config build from values of the pool config section + useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" + sentinel: + # name of master node + master: "${REDIS_MASTER:}" + # comma-separated list of "host:port" pairs of sentinels + sentinels: "${REDIS_SENTINELS:}" + # password to authenticate with sentinel + password: "${REDIS_SENTINEL_PASSWORD:}" + # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" # db index db: "${REDIS_DB:0}" diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 4e8167d89d..5de2484860 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -46,7 +46,7 @@ cache: type: "${CACHE_TYPE:redis}" redis: - # standalone or cluster + # standalone or cluster or sentinel connection: type: "${REDIS_CONNECTION_TYPE:standalone}" standalone: @@ -66,6 +66,16 @@ redis: nodes: "${REDIS_NODES:}" # Maximum number of redirects to follow when executing commands across the cluster. max-redirects: "${REDIS_MAX_REDIRECTS:12}" + # if set false will be used pool config build from values of the pool config section + useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" + sentinel: + # name of master node + master: "${REDIS_MASTER:}" + # comma-separated list of "host:port" pairs of sentinels + sentinels: "${REDIS_SENTINELS:}" + # password to authenticate with sentinel + password: "${REDIS_SENTINEL_PASSWORD:}" + # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" # db index db: "${REDIS_DB:0}" diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index 1e0b1ebcd4..ed25d00732 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -46,7 +46,7 @@ cache: type: "${CACHE_TYPE:redis}" redis: - # standalone or cluster + # standalone or cluster or sentinel connection: type: "${REDIS_CONNECTION_TYPE:standalone}" standalone: @@ -66,6 +66,16 @@ redis: nodes: "${REDIS_NODES:}" # Maximum number of redirects to follow when executing commands across the cluster. max-redirects: "${REDIS_MAX_REDIRECTS:12}" + # if set false will be used pool config build from values of the pool config section + useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" + sentinel: + # name of master node + master: "${REDIS_MASTER:}" + # comma-separated list of "host:port" pairs of sentinels + sentinels: "${REDIS_SENTINELS:}" + # password to authenticate with sentinel + password: "${REDIS_SENTINEL_PASSWORD:}" + # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" # db index db: "${REDIS_DB:0}" diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index 9f086bcbc5..f7fa3902b8 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -46,7 +46,7 @@ cache: type: "${CACHE_TYPE:redis}" redis: - # standalone or cluster + # standalone or cluster or sentinel connection: type: "${REDIS_CONNECTION_TYPE:standalone}" standalone: @@ -66,6 +66,16 @@ redis: nodes: "${REDIS_NODES:}" # Maximum number of redirects to follow when executing commands across the cluster. max-redirects: "${REDIS_MAX_REDIRECTS:12}" + # if set false will be used pool config build from values of the pool config section + useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" + sentinel: + # name of master node + master: "${REDIS_MASTER:}" + # comma-separated list of "host:port" pairs of sentinels + sentinels: "${REDIS_SENTINELS:}" + # password to authenticate with sentinel + password: "${REDIS_SENTINEL_PASSWORD:}" + # if set false will be used pool config build from values of the pool config section useDefaultPoolConfig: "${REDIS_USE_DEFAULT_POOL_CONFIG:true}" # db index db: "${REDIS_DB:0}" From 877c917f08b4815672ffc6598d438fbbdaebffa1 Mon Sep 17 00:00:00 2001 From: kalytka Date: Thu, 1 Jun 2023 14:53:13 +0300 Subject: [PATCH 108/207] new rulenode-core-config.js --- .../resources/public/static/rulenode/rulenode-core-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js index 69953bd64f..414c734227 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js +++ b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js @@ -1 +1 @@ -System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/platform-browser","@angular/material/select","@angular/material/core","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/icon","@angular/material/chips","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/material/tooltip","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","rxjs","@angular/material/expansion","@home/components/public-api","tslib","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@angular/material/slide-toggle","@home/components/relation/relation-filters.component","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@angular/material/button-toggle","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,u,p,d,c,f,g,y,x,b,h,C,v,F,L,k,T,I,N,S,q,M,A,G,E,D,V,w,P,R,O,H,K,B,U,z,_,j,$,Q,J,Y,W,X,Z,ee,te,ne,re,oe,ae,ie,le,se,me,ue,pe,de,ce,fe,ge,ye,xe,be,he,Ce,ve,Fe,Le,ke,Te,Ie,Ne,Se,qe,Me,Ae,Ge,Ee,De,Ve,we,Pe,Re,Oe,He,Ke,Be,Ue,ze,_e,je;return{setters:[function(e){t=e,n=e.Component,r=e.Pipe,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.NgModule},function(e){s=e.RuleNodeConfigurationComponent,m=e.AttributeScope,u=e.telemetryTypeTranslations,p=e.ServiceType,d=e.ScriptLanguage,c=e.AlarmSeverity,f=e.alarmSeverityTranslations,g=e.EntitySearchDirection,y=e.entitySearchDirectionTranslations,x=e.EntityType,b=e.PageComponent,h=e.coerceBoolean,C=e.MessageType,v=e.messageTypeNames,F=e,L=e.SharedModule,k=e.AggregationType,T=e.aggregationTranslations,I=e.NotificationType,N=e.SlackChanelType,S=e.SlackChanelTypesTranslateMap,q=e.alarmStatusTranslations,M=e.AlarmStatus},function(e){A=e},function(e){G=e,E=e.Validators,D=e.NgControl,V=e.NG_VALUE_ACCESSOR,w=e.NG_VALIDATORS,P=e.FormControl,R=e.UntypedFormControl},function(e){O=e,H=e.CommonModule},function(e){K=e},function(e){B=e},function(e){U=e},function(e){z=e},function(e){_=e},function(e){j=e},function(e){$=e},function(e){Q=e},function(e){J=e},function(e){Y=e.getCurrentAuthState,W=e,X=e.isDefinedAndNotNull,Z=e.isObject,ee=e.isNotEmptyStr},function(e){te=e},function(e){ne=e},function(e){re=e},function(e){oe=e.ENTER,ae=e.COMMA,ie=e.SEMICOLON},function(e){le=e},function(e){se=e},function(e){me=e},function(e){ue=e},function(e){pe=e.coerceBooleanProperty},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e},function(e){xe=e.tap,be=e.map,he=e.mergeMap,Ce=e.takeUntil,ve=e.startWith,Fe=e.share,Le=e.distinctUntilChanged},function(e){ke=e},function(e){Te=e},function(e){Ie=e.of,Ne=e.Subject},function(e){Se=e},function(e){qe=e.HomeComponentsModule},function(e){Me=e.__decorate},function(e){Ae=e},function(e){Ge=e},function(e){Ee=e},function(e){De=e},function(e){Ve=e},function(e){we=e},function(e){Pe=e},function(e){Re=e},function(e){Oe=e},function(e){He=e},function(e){Ke=e},function(e){Be=e},function(e){Ue=e},function(e){ze=e},function(e){_e=e},function(e){je=e}],execute:function(){class $e extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",$e),$e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$e,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qe{constructor(e){this.sanitizer=e}transform(e){return this.sanitizer.bypassSecurityTrustHtml(e)}}e("SafeHtmlPipe",Qe),Qe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,deps:[{token:j.DomSanitizer}],target:t.ɵɵFactoryTarget.Pipe}),Qe.ɵpipe=t.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Qe,name:"safeHtml"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,decorators:[{type:r,args:[{name:"safeHtml"}]}],ctorParameters:function(){return[{type:j.DomSanitizer}]}});class Je extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[E.required,E.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[E.required,E.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",Je),Je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Je,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Ye extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===m.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",Ye),Ye.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ye.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ye,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class We extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[E.required]]})}}e("CheckPointConfigComponent",We),We.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),We.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:We,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,decorators:[{type:n,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Xe extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[E.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===d.JS?[E.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===d.TBEL?[E.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.clearAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",r=this.clearAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.clearAlarmConfigForm.get(t).setValue(e)}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",Xe),Xe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xe,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Ze extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.alarmSeverities=Object.keys(c),this.alarmSeverityTranslationMap=f,this.separatorKeysCodes=[oe,ae,ie],this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([E.required]),this.createAlarmConfigForm.get("severity").setValidators([E.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==d.TBEL||this.tbelEnabled||(r=d.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===d.JS?[E.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===d.TBEL?[E.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.createAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",r=this.createAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.createAlarmConfigForm.get(t).setValue(e)}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",Ze),Ze.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ze,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ze.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ze,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ze,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class et extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[E.required]],entityType:[e?e.entityType:null,[E.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[E.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[E.required,E.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==x.DEVICE&&t!==x.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([E.required,E.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",et),et.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:et,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),et.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:et,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:et,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class tt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[E.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[E.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[E.required,E.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([E.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",tt),tt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,E.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,E.required]})}}e("DeviceProfileConfigComponent",nt),nt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class rt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[E.required,E.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[E.required,E.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(){const e=this.generatorConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",r=this.generatorConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.generatorConfigForm.get(t).setValue(e)}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}var ot;e("GeneratorConfigComponent",rt),rt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rt,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),rt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rt,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rt,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(ot||(ot={}));const at=new Map([[ot.CUSTOMER,"tb.rulenode.originator-customer"],[ot.TENANT,"tb.rulenode.originator-tenant"],[ot.RELATED,"tb.rulenode.originator-related"],[ot.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[ot.ENTITY,"tb.rulenode.originator-entity"]]);var it;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(it||(it={}));const lt=new Map([[it.CIRCLE,"tb.rulenode.perimeter-circle"],[it.POLYGON,"tb.rulenode.perimeter-polygon"]]);var st;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(st||(st={}));const mt=new Map([[st.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[st.SECONDS,"tb.rulenode.time-unit-seconds"],[st.MINUTES,"tb.rulenode.time-unit-minutes"],[st.HOURS,"tb.rulenode.time-unit-hours"],[st.DAYS,"tb.rulenode.time-unit-days"]]);var ut;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(ut||(ut={}));const pt=new Map([[ut.METER,"tb.rulenode.range-unit-meter"],[ut.KILOMETER,"tb.rulenode.range-unit-kilometer"],[ut.FOOT,"tb.rulenode.range-unit-foot"],[ut.MILE,"tb.rulenode.range-unit-mile"],[ut.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var dt,ct;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(dt||(dt={})),function(e){e.NAME="name",e.CREATED_TIME="createdTime",e.TYPE="type",e.FIRST_NAME="firstName",e.LAST_NAME="lastName",e.EMAIL="email",e.TITLE="title",e.COUNTRY="county",e.STATE="state",e.CITY="city",e.ADDRESS="address",e.ADDRESS2="address2",e.ZIP="zip",e.PHONE="phone",e.LABEL="label"}(ct||(ct={}));const ft=new Map([[ct.NAME,"tb.rulenode.name"],[ct.CREATED_TIME,"tb.rulenode.created-time"],[ct.TYPE,"tb.rulenode.type"],[ct.FIRST_NAME,"tb.rulenode.first-name"],[ct.LAST_NAME,"tb.rulenode.last-name"],[ct.EMAIL,"tb.rulenode.entity-details-email"],[ct.TITLE,"tb.rulenode.entity-details-title"],[ct.COUNTRY,"tb.rulenode.entity-details-country"],[ct.STATE,"tb.rulenode.entity-details-state"],[ct.CITY,"tb.rulenode.entity-details-city"],[ct.ADDRESS,"tb.rulenode.entity-details-address"],[ct.ADDRESS2,"tb.rulenode.entity-details-address2"],[ct.ZIP,"tb.rulenode.entity-details-zip"],[ct.PHONE,"tb.rulenode.entity-details-phone"],[ct.LABEL,"tb.rulenode.label"]]),gt=new Map([[dt.ID,"tb.rulenode.entity-details-id"],[dt.TITLE,"tb.rulenode.entity-details-title"],[dt.COUNTRY,"tb.rulenode.entity-details-country"],[dt.STATE,"tb.rulenode.entity-details-state"],[dt.CITY,"tb.rulenode.entity-details-city"],[dt.ZIP,"tb.rulenode.entity-details-zip"],[dt.ADDRESS,"tb.rulenode.entity-details-address"],[dt.ADDRESS2,"tb.rulenode.entity-details-address2"],[dt.PHONE,"tb.rulenode.entity-details-phone"],[dt.EMAIL,"tb.rulenode.entity-details-email"],[dt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var yt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(yt||(yt={}));const xt=new Map([[yt.FIRST,"tb.rulenode.first"],[yt.LAST,"tb.rulenode.last"],[yt.ALL,"tb.rulenode.all"]]);var bt,ht;!function(e){e.ASC="ASC",e.DESC="DESC"}(bt||(bt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(ht||(ht={}));const Ct=new Map([[bt.ASC,"tb.rulenode.ascending"],[bt.DESC,"tb.rulenode.descending"]]);var vt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(vt||(vt={}));const Ft=new Map([[vt.STANDARD,"tb.rulenode.sqs-queue-standard"],[vt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),Lt=["anonymous","basic","cert.PEM"],kt=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Tt=["sas","cert.PEM"],It=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var Nt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(Nt||(Nt={}));const St=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],qt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Mt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Mt||(Mt={}));const At=new Map([[Mt.CUSTOM,{value:Mt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Mt.ADD,{value:Mt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Mt.SUB,{value:Mt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Mt.MULT,{value:Mt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Mt.DIV,{value:Mt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Mt.SIN,{value:Mt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Mt.SINH,{value:Mt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Mt.COS,{value:Mt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Mt.COSH,{value:Mt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Mt.TAN,{value:Mt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Mt.TANH,{value:Mt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Mt.ACOS,{value:Mt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Mt.ASIN,{value:Mt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Mt.ATAN,{value:Mt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Mt.ATAN2,{value:Mt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Mt.EXP,{value:Mt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Mt.EXPM1,{value:Mt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Mt.SQRT,{value:Mt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Mt.CBRT,{value:Mt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Mt.GET_EXP,{value:Mt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Mt.HYPOT,{value:Mt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Mt.LOG,{value:Mt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Mt.LOG10,{value:Mt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Mt.LOG1P,{value:Mt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Mt.CEIL,{value:Mt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Mt.FLOOR,{value:Mt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Mt.FLOOR_DIV,{value:Mt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Mt.FLOOR_MOD,{value:Mt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Mt.ABS,{value:Mt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Mt.MIN,{value:Mt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Mt.MAX,{value:Mt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Mt.POW,{value:Mt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Mt.SIGNUM,{value:Mt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Mt.RAD,{value:Mt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Mt.DEG,{value:Mt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Gt,Et,Dt;!function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Gt||(Gt={})),function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Et||(Et={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(Dt||(Dt={}));const Vt=new Map([[Gt.ATTRIBUTE,"tb.rulenode.attribute-type"],[Gt.TIME_SERIES,"tb.rulenode.time-series-type"],[Gt.CONSTANT,"tb.rulenode.constant-type"],[Gt.MESSAGE_BODY,"tb.rulenode.message-body-type"],[Gt.MESSAGE_METADATA,"tb.rulenode.message-metadata-type"]]),wt=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var Pt,Rt;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(Pt||(Pt={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(Rt||(Rt={}));const Ot=new Map([[Pt.SHARED_SCOPE,"tb.rulenode.shared-scope"],[Pt.SERVER_SCOPE,"tb.rulenode.server-scope"],[Pt.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class Ht extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=it,this.perimeterTypes=Object.keys(it),this.perimeterTypeTranslationMap=lt,this.rangeUnits=Object.keys(ut),this.rangeUnitTranslationMap=pt,this.timeUnits=Object.keys(st),this.timeUnitsTranslationMap=mt}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[E.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[E.required]],perimeterType:[e?e.perimeterType:null,[E.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[E.required,E.min(1),E.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[E.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[E.required,E.min(1),E.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[E.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([E.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==it.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([E.required,E.min(-90),E.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([E.required,E.min(-180),E.max(180)]),this.geoActionConfigForm.get("range").setValidators([E.required,E.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([E.required])),t||n!==it.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([E.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",Ht),Ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ht,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Kt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.logConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",r=this.logConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.logConfigForm.get(t).setValue(e)}))}onValidate(){this.logConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",Kt),Kt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Kt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kt,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Bt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[E.required,E.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[E.required]]})}}e("MsgCountConfigComponent",Bt),Bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Bt,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Ut extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[E.required,E.min(1),E.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([E.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([E.required,E.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",Ut),Ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ut,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class zt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]]})}}e("PushToCloudConfigComponent",zt),zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zt,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class _t extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]]})}}e("PushToEdgeConfigComponent",_t),_t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_t,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",jt),jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jt,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class $t extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[E.required,E.min(0)]]})}}e("RpcRequestConfigComponent",$t),$t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$t,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required]],value:[e[n],[E.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[E.required]],value:["",[E.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Qt),Qt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qt,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:V,useExisting:a((()=>Qt)),multi:!0},{provide:w,useExisting:a((()=>Qt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:V,useExisting:a((()=>Qt)),multi:!0},{provide:w,useExisting:a((()=>Qt)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class Jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[E.required,E.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[E.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",Jt),Jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jt,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Yt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[E.required,E.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Yt),Yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yt,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Wt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[E.required,E.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[E.required,E.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Wt),Wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Wt,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Xt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]],keys:[e?e.keys:null,[E.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",Xt),Xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xt,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Zt extends b{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup())}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=At,this.ArgumentType=Gt,this.attributeScopeMap=Ot,this.argumentTypeResultMap=Vt,this.arguments=Object.values(Gt),this.attributeScope=Object.values(Pt),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.argumentsFormGroup=this.fb.group({}),this.argumentsFormGroup.addControl("arguments",this.fb.array([])),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray(),n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):this.argumentsFormGroup.enable({emitEvent:!1})}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()));const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t)),this.setupArgumentsFormGroup(),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()})))}removeArgument(e){this.argumentsFormGroup.get("arguments").removeAt(e),this.updateArgumentNames()}addArgument(){const e=this.argumentsFormGroup.get("arguments"),t=this.createArgumentControl(null,e.length);e.push(t)}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Mt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([E.minLength(this.minArgs),E.maxLength(this.maxArgs)]),this.argumentsFormGroup.get("arguments").value.length>this.maxArgs&&(this.argumentsFormGroup.get("arguments").controls.length=this.maxArgs);this.argumentsFormGroup.get("arguments").value.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!0}),n.get("defaultValue").updateValueAndValidity({emitEvent:!0})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Gt.ATTRIBUTE?e.get("attributeScope").enable():e.get("attributeScope").disable(),t&&t!==Gt.CONSTANT?e.get("defaultValue").enable():e.get("defaultValue").disable()}updateArgumentNames(){this.argumentsFormGroup.get("arguments").controls.forEach(((e,t)=>{e.get("name").setValue(wt[t])}))}updateModel(){const e=this.argumentsFormGroup.get("arguments").value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Zt),Zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Zt,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:V,useExisting:a((()=>Zt)),multi:!0},{provide:w,useExisting:a((()=>Zt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"],dependencies:[{kind:"directive",type:O.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ge.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:ge.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:ye.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:ye.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:ye.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:V,useExisting:a((()=>Zt)),multi:!0},{provide:w,useExisting:a((()=>Zt)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class en extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...At.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(xe((e=>{let t;t="string"==typeof e&&Mt[e]?Mt[e]:null,this.updateView(t)})),be((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=At.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",en),en.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:en,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),en.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:en,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:V,useExisting:a((()=>en)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:en,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:V,useExisting:a((()=>en)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Mt,this.ArgumentTypeResult=Et,this.argumentTypeResultMap=Vt,this.attributeScopeMap=Ot,this.argumentsResult=Object.values(Et),this.attributeScopeResult=Object.values(Rt)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[E.required]],arguments:[e?e.arguments:null,[E.required]],customFunction:[e?e.customFunction:"",[E.required]],result:this.fb.group({type:[e?e.result.type:null,[E.required]],attributeScope:[e?e.result.attributeScope:null],key:[e?e.result.key:"",[E.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result").get("type").value;t===Mt.CUSTOM?this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Et.ATTRIBUTE?this.mathFunctionConfigForm.get("result").get("attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result").get("attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result").get("attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",tn),tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tn,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Zt,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:en,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tn,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nn{constructor(e,t){this.store=e,this.fb=t,this.subscriptSizing="fixed",this.searchText="",this.dirty=!1,this.messageTypes=["POST_ATTRIBUTES_REQUEST","POST_TELEMETRY_REQUEST"],this.propagateChange=e=>{},this.messageTypeFormGroup=this.fb.group({messageType:[null,[E.required,E.maxLength(255)]]})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.outputMessageTypes=this.messageTypeFormGroup.get("messageType").valueChanges.pipe(xe((e=>{this.updateView(e)})),be((e=>e||"")),he((e=>this.fetchMessageTypes(e))))}writeValue(e){this.searchText="",this.modelValue=e,this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1}),this.dirty=!0}onFocus(){this.dirty&&(this.messageTypeFormGroup.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0}),this.dirty=!1)}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}displayMessageTypeFn(e){return e||void 0}fetchMessageTypes(e,t=!1){return this.searchText=e,Ie(this.messageTypes).pipe(be((n=>n.filter((n=>t?!!e&&n===e:!e||n.toUpperCase().startsWith(e.toUpperCase()))))))}clear(){this.messageTypeFormGroup.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}}e("OutputMessageTypeAutocompleteComponent",nn),nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nn,selector:"tb-output-message-type-autocomplete",inputs:{autocompleteHint:"autocompleteHint",subscriptSizing:"subscriptSizing"},providers:[{provide:V,useExisting:a((()=>nn)),multi:!0}],viewQueries:[{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0,static:!0}],ngImport:t,template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:V,useExisting:a((()=>nn)),multi:!0}],template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{messageTypeInput:[{type:o,args:["messageTypeInput",{static:!0}]}],autocompleteHint:[{type:i}],subscriptSizing:[{type:i}]}});class rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.destroy$=new Ne,this.serviceType=p.TB_RULE_ENGINE,this.deduplicationStrategie=yt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=xt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[X(e?.interval)?e.interval:null,[E.required,E.min(1)]],strategy:[X(e?.strategy)?e.strategy:null,[E.required]],outMsgType:[X(e?.outMsgType)?e.outMsgType:null,[E.required]],queueName:[X(e?.queueName)?e.queueName:null,[E.required]],maxPendingMsgs:[X(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[E.required,E.min(1),E.max(1e3)]],maxRetries:[X(e?.maxRetries)?e.maxRetries:null,[E.required,E.min(0),E.max(100)]]}),this.deduplicationConfigForm.get("strategy").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.enableControl(e)}))}updateValidators(e){this.enableControl(this.deduplicationConfigForm.get("strategy").value)}validatorTriggers(){return["strategy"]}enableControl(e){e===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("DeduplicationConfigComponent",rn),rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rn,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:nn,selector:"tb-output-message-type-autocomplete",inputs:["autocompleteHint","subscriptSizing"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class on extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[e[n],[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",on),on.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:on,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),on.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:on,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:V,useExisting:a((()=>on)),multi:!0},{provide:w,useExisting:a((()=>on)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n \n \n \n
\n
\n {{ hintText }}\n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),Me([h()],on.prototype,"disabled",void 0),Me([h()],on.prototype,"uniqueKeyValuePairValidator",void 0),Me([h()],on.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:on,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:V,useExisting:a((()=>on)),multi:!0},{provide:w,useExisting:a((()=>on)),multi:!0}],template:'
\n
\n \n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n \n \n \n
\n
\n {{ hintText }}\n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class an{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne}ngOnInit(){this.slideToggleControlGroup=this.fb.group({slideToggleControl:[null,[]]}),this.slideToggleControlGroup.get("slideToggleControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.slideToggleControlGroup.get("slideToggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SlideToggleComponent",an),an.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:an,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),an.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:an,selector:"tb-slide-toggle",inputs:{slideToggleName:"slideToggleName",slideToggleTooltip:"slideToggleTooltip"},providers:[{provide:V,useExisting:a((()=>an)),multi:!0}],ngImport:t,template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"],dependencies:[{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:De.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:an,decorators:[{type:n,args:[{selector:"tb-slide-toggle",providers:[{provide:V,useExisting:a((()=>an)),multi:!0}],template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{slideToggleName:[{type:i}],slideToggleTooltip:[{type:i}]}});class ln extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[E.min(1)]],relationType:[null],deviceTypes:[null,[E.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",ln),ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ln,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ln,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>ln)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ge.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["label","required","disabled","entityType"]},{kind:"component",type:Ee.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","required","disabled","subscriptSizing"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ln,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:V,useExisting:a((()=>ln)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class sn{set required(e){this.requiredValue=pe(e)}get required(){return this.requiredValue}}e("FieldsetComponent",sn),sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sn,deps:[],target:t.ɵɵFactoryTarget.Component}),sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:sn,selector:"tb-fieldset-component",inputs:{label:"label",required:"required"},ngImport:t,template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sn,decorators:[{type:n,args:[{selector:"tb-fieldset-component",template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],propDecorators:{label:[{type:i}],required:[{type:i}]}});class mn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[E.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",mn),mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:mn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>mn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ve.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:V,useExisting:a((()=>mn)),multi:!0}],template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class un extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.message-type",this.separatorKeysCodes=[oe,ae,ie],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(C))this.messageTypesList.push({name:v.get(C[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchMessageTypes(e))),Fe())}ngAfterViewInit(){}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return!!(e&&null!=e&&e.length>0)}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ie(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t=null;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:un,deps:[{token:A.Store},{token:_.TranslateService},{token:F.TruncatePipe},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:un,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:V,useExisting:a((()=>un)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:V,useExisting:a((()=>un)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:F.TruncatePipe},{type:G.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class pn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRquired=!0,this.allCredentialsTypes=Lt,this.credentialsTypeTranslationsMap=kt,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[E.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.pipe(Le()).subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){X(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators(!1))}setDisabledState(e){e?this.credentialsConfigFormGroup.disable():(this.credentialsConfigFormGroup.enable(),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([E.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRquired?[E.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(E.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",pn),pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:pn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRquired:"passwordFieldRquired"},providers:[{provide:V,useExisting:a((()=>pn)),multi:!0},{provide:w,useExisting:a((()=>pn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:O.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:O.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Se.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:V,useExisting:a((()=>pn)),multi:!0},{provide:w,useExisting:a((()=>pn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRquired:[{type:i}]}});class dn{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne,this.fetchTo=Dt}ngOnInit(){this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("MsgMetadataChipComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:dn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText"},providers:[{provide:V,useExisting:a((()=>dn)),multi:!0}],ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.message\' | translate }}\n {{ \'tb.rulenode.metadata\' | translate }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"],dependencies:[{kind:"component",type:se.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:se.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:V,useExisting:a((()=>dn)),multi:!0}],template:'
\n \n \n {{ \'tb.rulenode.message\' | translate }}\n {{ \'tb.rulenode.metadata\' | translate }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{labelText:[{type:i}]}});class cn extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new Ne,this.sourceFieldSubcritption=[],this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({}),this.svListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required]],value:[e[n],[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.svListFormGroup.setControl("keyVals",this.fb.array(t));for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e);this.valueChangeSubscription=this.svListFormGroup.valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.updateModel()}))}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value)t.push(this.selectOptions.find((t=>t===e.key)));const n=[];for(const r of this.selectOptions)X(t.find((e=>e===r)))&&r!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.svListFormGroup.get("keyVals").removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){const e=this.svListFormGroup.get("keyVals");e.push(this.fb.group({key:["",[E.required]],value:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(e.controls[e.length-1])}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(Ce(this.destroy$)).subscribe((t=>{e.get("value").patchValue(this.targetKeyPrefix+t[0].toUpperCase()+t.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{kvMapRequired:!0}:this.svListFormGroup.valid?null:{kvFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cn,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:cn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",selectOptionsTranslate:"selectOptionsTranslate",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:V,useExisting:a((()=>cn)),multi:!0},{provide:w,useExisting:a((()=>cn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n \n {{ selectText }}\n \n \n {{selectOptionsTranslate.get(option) | translate}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n \n \n
\n
\n {{ hintText }}\n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),Me([h()],cn.prototype,"disabled",void 0),Me([h()],cn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:V,useExisting:a((()=>cn)),multi:!0},{provide:w,useExisting:a((()=>cn)),multi:!0}],template:'
\n
\n \n
\n
\n
\n \n {{ selectText }}\n \n \n {{selectOptionsTranslate.get(option) | translate}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n \n \n
\n
\n {{ hintText }}\n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],selectOptionsTranslate:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class fn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:fn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>fn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ve.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:V,useExisting:a((()=>fn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class gn{set enableFieldToggle(e){this._enableFieldToggle=pe(e)}get enableFieldToggle(){return this._enableFieldToggle}constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne,this.DataToFetch=ht}ngOnInit(){this.toggleControlGroup=this.fb.group({toggleControl:[null,[]]}),this.toggleControlGroup.get("toggleControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.toggleControlGroup.get("toggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("FetchToDataToggleComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:gn,selector:"tb-fetch-to-data-toggle",inputs:{enableFieldToggle:"enableFieldToggle"},providers:[{provide:V,useExisting:a((()=>gn)),multi:!0}],ngImport:t,template:'
\n \n {{ \'tb.rulenode.attributes\' | translate }}\n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n {{ \'tb.rulenode.fields\' | translate }}\n \n
\n',styles:[":host ::ng-deep{margin-bottom:12px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;width:215px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Re.MatButtonToggleGroup,selector:"mat-button-toggle-group",inputs:["appearance","name","vertical","value","multiple","disabled"],outputs:["valueChange","change"],exportAs:["matButtonToggleGroup"]},{kind:"component",type:Re.MatButtonToggle,selector:"mat-button-toggle",inputs:["disableRipple","aria-label","aria-labelledby","id","name","value","tabIndex","appearance","checked","disabled"],outputs:["change"],exportAs:["matButtonToggle"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-fetch-to-data-toggle",providers:[{provide:V,useExisting:a((()=>gn)),multi:!0}],template:'
\n \n {{ \'tb.rulenode.attributes\' | translate }}\n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n {{ \'tb.rulenode.fields\' | translate }}\n \n
\n',styles:[":host ::ng-deep{margin-bottom:12px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;width:215px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{enableFieldToggle:[{type:i}]}});class yn{constructor(e,t,n){this.store=e,this.translate=t,this.fb=n,this.destroy$=new Ne,this.separatorKeysCodes=[oe,ae,ie]}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[null,[]],sharedAttributeNames:[null,[]],serverAttributeNames:[null,[]],latestTsKeyNames:[null,[]],getLatestValueWithTs:[!1,[]]}),this.attributeControlGroup.valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.attributeControlGroup.patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}removeKey(e,t){const n=this.attributeControlGroup.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.attributeControlGroup.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.attributeControlGroup.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.attributeControlGroup.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}clearChipGrid(e){this.attributeControlGroup.get(e).patchValue([],{emitEvent:!0})}}e("SelectAttributesComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:yn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:V,useExisting:a((()=>yn)),multi:!0}],ngImport:t,template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin:10px 0 12px;display:block}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:V,useExisting:a((()=>yn)),multi:!0}],template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin:10px 0 12px;display:block}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class xn{}e("RulenodeCoreConfigCommonModule",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),xn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:xn,declarations:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn],imports:[H,L,qe],exports:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn]}),xn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,imports:[H,L,qe]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,decorators:[{type:l,args:[{declarations:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn],imports:[H,L,qe],exports:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn]}]}]});class bn{}e("RuleNodeCoreConfigActionModule",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),bn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:bn,declarations:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn],imports:[H,L,qe,xn],exports:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn]}),bn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,imports:[H,L,qe,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,decorators:[{type:l,args:[{declarations:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn],imports:[H,L,qe,xn],exports:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn]}]}]});class hn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[E.min(0),E.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:X(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:X(e?.outputValueKey)?e.outputValueKey:null,useCache:!X(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!X(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:X(e?.periodValueKey)?e.periodValueKey:null,round:X(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!X(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return e.inputValueKey=e.inputValueKey.trim(),e.outputValueKey=e.outputValueKey.trim(),e}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([E.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:hn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Cn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n].trim();return e.dataMapping=t,e}prepareInputConfig(e){let t,n;return t=X(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Cn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class vn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[E.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return Z(e)&&(e.attributesControl={clientAttributeNames:X(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:X(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:X(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!X(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:X(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!X(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:vn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ln,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:yn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Fn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.entityDetailsTranslationsMap=gt,this.entityDetailsList=[],this.searchText="",this.displayDetailsFn=this.displayDetails.bind(this);for(const e of Object.keys(dt))this.entityDetailsList.push(dt[e]);this.detailsFormControl=new P(""),this.filteredEntityDetails=this.detailsFormControl.valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchEntityDetails(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return this.searchText="",this.detailsFormControl.patchValue("",{emitEvent:!0}),this.detailsList=e?e.detailsList:[],t=X(e?.addToMetadata)?e.addToMetadata?Dt.METADATA:Dt.DATA:e?.fetchTo?e.fetchTo:Dt.DATA,{detailsList:X(e?.detailsList)?e.detailsList:null,fetchTo:t}}prepareOutputConfig(e){return e.detailsList=this.detailsList,e}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[E.required]],fetchTo:[e.fetchTo,[]]}),this.detailsList=e?e.detailsList:[]}displayDetails(e){return e?this.translate.instant(gt.get(e)):void 0}fetchEntityDetails(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(this.entityDetailsList.filter((t=>this.translate.instant(gt.get(dt[t])).toUpperCase().includes(e))))}return Ie(this.entityDetailsList)}detailsFieldSelected(e){this.addDetailsField(e.option.value),this.clear("")}removeDetailsField(e){const t=this.detailsList.indexOf(e);t>=0&&(this.detailsList.splice(t,1),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}addDetailsField(e){this.detailsList||(this.detailsList=[]);-1===this.detailsList.indexOf(e)&&(this.detailsList.push(e),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}onEntityDetailsInputFocus(){this.detailsFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clearChipGrid(){this.detailsList=[],this.entityDetailsConfigForm.get("detailsList").patchValue([],{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}clear(e=""){this.detailsInput.nativeElement.value=e,this.detailsFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}}e("EntityDetailsConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Fn,selector:"tb-enrichment-node-entity-details-config",viewQueries:[{propertyName:"detailsInput",first:!0,predicate:["detailsInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]},propDecorators:{detailsInput:[{type:o,args:["detailsInput",{static:!1}]}]}});class Ln extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[oe,ae,ie],this.aggregationTypes=k,this.aggregations=Object.keys(k),this.aggregationTypesTranslations=T,this.fetchMode=yt,this.fetchModes=Object.keys(yt),this.deduplicationStrategiesTranslations=xt,this.samplingOrders=Object.keys(bt),this.samplingOrdersTranslate=Ct,this.timeUnits=Object.values(st),this.timeUnitsTranslationMap=mt,this.timeUnitMap={[st.MILLISECONDS]:1,[st.SECONDS]:1e3,[st.MINUTES]:6e4,[st.HOURS]:36e5,[st.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[]],aggregation:[e.aggregation,[E.required]],fetchMode:[e.fetchMode,[E.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,e.startIntervalPattern=e.startIntervalPattern.trim(),e.endIntervalPattern=e.endIntervalPattern.trim(),delete e.interval,e}prepareInputConfig(e){return Z(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:X(e?.aggregation)?e.aggregation:k.NONE,fetchMode:X(e?.fetchMode)?e.fetchMode:yt.FIRST,orderBy:X(e?.orderBy)?e.orderBy:bt.ASC,limit:X(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!X(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:X(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:X(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:st.MINUTES,endInterval:X(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:X(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:st.MINUTES},startIntervalPattern:X(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:X(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===yt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([E.required,E.min(2),E.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([E.required,E.min(1),E.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([E.required,E.min(1),E.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}fetchModeHintSelector(){let e;switch(this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value){case yt.ALL:e="tb.rulenode.all-mode-hint";break;case yt.LAST:e="tb.rulenode.last-mode-hint";break;case yt.FIRST:e="tb.rulenode.first-mode-hint"}return e}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}}e("GetTelemetryFromDatabaseConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ln,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ln,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n {{ deduplicationStrategiesTranslations.get(fetchMode) | translate}}\n \n
\n {{ fetchModeHintSelector() | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle mat-button-toggle{width:215px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .additional-inputs{margin-bottom:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:Re.MatButtonToggleGroup,selector:"mat-button-toggle-group",inputs:["appearance","name","vertical","value","multiple","disabled"],outputs:["valueChange","change"],exportAs:["matButtonToggleGroup"]},{kind:"component",type:Re.MatButtonToggle,selector:"mat-button-toggle",inputs:["disableRipple","aria-label","aria-labelledby","id","name","value","tabIndex","appearance","checked","disabled"],outputs:["change"],exportAs:["matButtonToggle"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n {{ deduplicationStrategiesTranslations.get(fetchMode) | translate}}\n \n
\n {{ fetchModeHintSelector() | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle mat-button-toggle{width:215px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .additional-inputs{margin-bottom:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class kn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return Z(e)&&(e.attributesControl={clientAttributeNames:X(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:X(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:X(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!X(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA,tellFailureIfAbsent:!!X(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:X(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:kn,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:yn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorFields=[],this.originatorFieldsTranslations=ft;for(const e of Object.keys(ct))this.originatorFields.push(ct[e])}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){for(const t of Object.keys(e.dataMapping))e.dataMapping[t]=e.dataMapping[t].trim();return e}prepareInputConfig(e){return{dataMapping:X(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:X(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[E.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Tn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:cn,selector:"tb-sv-map-config",inputs:["selectOptions","selectOptionsTranslate","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class In extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht,this.originatorFieldsTranslations=ft,this.originatorFields=[],this.destroy$=new Ne,this.defaultKvMap={serialNumber:"sn"},this.defaultSvMap={name:"relatedEntityName",type:"relatedEntityType"},this.dataToFetchPrevValue="";for(const e of Object.keys(ct))this.originatorFields.push(ct[e])}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n].trim();return e.dataMapping=t,e}prepareInputConfig(e){let t;return X(e?.telemetry)?this.dataToFetchPrevValue=e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:this.dataToFetchPrevValue=X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,t=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{relationsQuery:X(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:this.dataToFetchPrevValue,dataMapping:t,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[E.required]],dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo,[]]}),this.relatedAttributesConfigForm.get("dataToFetch").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{e===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultSvMap,{emitEvent:!1}),e!==ht.FIELDS&&this.dataToFetchPrevValue===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultKvMap,{emitEvent:!1}),this.dataToFetchPrevValue=e}))}msgMetadataChipLabel(){switch(this.relatedAttributesConfigForm.get("dataToFetch").value){case ht.ATTRIBUTES:return"tb.rulenode.add-mapped-attribute-to";case ht.LATEST_TELEMETRY:return"tb.rulenode.add-mapped-latest-telemetry-to";case ht.FIELDS:return"tb.rulenode.add-mapped-fields-to"}}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("RelatedAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:In,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:In,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:mn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:cn,selector:"tb-sv-map-config",inputs:["selectOptions","selectOptionsTranslate","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Nn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=X(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Nn,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Sn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Sn,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class qn{}e("RulenodeCoreConfigEnrichmentModule",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),qn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:qn,declarations:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn],imports:[H,L,xn],exports:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn]}),qn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,decorators:[{type:l,args:[{declarations:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn],imports:[H,L,xn],exports:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn]}]}]});class Mn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Tt,this.azureIotHubCredentialsTypeTranslationsMap=It}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[E.required,E.min(1),E.max(200)]],clientId:[e?e.clientId:null,[E.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[E.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([E.required]);break;case"cert.PEM":t.get("privateKey").setValidators([E.required]),t.get("privateKeyFileName").setValidators([E.required]),t.get("cert").setValidators([E.required]),t.get("certFileName").setValidators([E.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Mn,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:O.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:O.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Se.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class An extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=St,this.ToByteStandartCharsetTypeTranslationMap=qt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[E.required]],retries:[e?e.retries:null,[E.min(0)]],batchSize:[e?e.batchSize:null,[E.min(0)]],linger:[e?e.linger:null,[E.min(0)]],bufferMemory:[e?e.bufferMemory:null,[E.min(0)]],acks:[e?e.acks:null,[E.required]],keySerializer:[e?e.keySerializer:null,[E.required]],valueSerializer:[e?e.valueSerializer:null,[E.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([E.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:An,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:An,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Gn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[]}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[E.required,E.min(1),E.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ee(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]}),this.subscriptions.push(this.mqttConfigForm.get("clientId").valueChanges.subscribe((e=>{ee(e)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1})})))}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}}e("MqttConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Gn,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:pn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRquired"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class En extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=I,this.entityType=x}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[E.required]],targets:[e?e.targets:[],[E.required]]})}}e("NotificationConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:En,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:En,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:Oe.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:He.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","disabled","notificationTypes"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Dn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[E.required]],topicName:[e?e.topicName:null,[E.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[E.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[E.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Dn,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Vn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[E.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[E.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Vn,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class wn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(Nt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[E.required]],requestMethod:[e?e.requestMethod:null,[E.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],trimDoubleQuotes:[!!e&&e.trimDoubleQuotes,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[E.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[E.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[E.required,E.min(1),E.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([E.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([E.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",wn),wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:wn,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:pn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRquired"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wn,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Pn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([E.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([E.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([E.required,E.min(1),E.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([E.required,E.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[E.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[E.required,E.min(1),E.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",Pn),Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Pn,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ke.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pn,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[E.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[E.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([E.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Rn,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Be.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class On extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(N),this.slackChanelTypesTranslateMap=S}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[E.required]],conversationType:[e?e.conversationType:null,[E.required]],conversation:[e?e.conversation:null,[E.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([E.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:On,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:On,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ze.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Hn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[E.required]],accessKeyId:[e?e.accessKeyId:null,[E.required]],secretAccessKey:[e?e.secretAccessKey:null,[E.required]],region:[e?e.region:null,[E.required]]})}}e("SnsConfigComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Hn,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Kn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=vt,this.sqsQueueTypes=Object.keys(vt),this.sqsQueueTypeTranslationsMap=Ft}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[E.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[E.required]],delaySeconds:[e?e.delaySeconds:null,[E.min(0),E.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[E.required]],secretAccessKey:[e?e.secretAccessKey:null,[E.required]],region:[e?e.region:null,[E.required]]})}}e("SqsConfigComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kn,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Bn{}e("RulenodeCoreConfigExternalModule",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Bn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Bn,declarations:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On],imports:[H,L,qe,xn],exports:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On]}),Bn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,imports:[H,L,qe,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,decorators:[{type:l,args:[{declarations:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On],imports:[H,L,qe,xn],exports:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On]}]}]});class Un extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.alarmStatusTranslationsMap=q,this.alarmStatusList=[],this.searchText="",this.displayStatusFn=this.displayStatus.bind(this);for(const e of Object.keys(M))this.alarmStatusList.push(M[e]);this.statusFormControl=new R(""),this.filteredAlarmStatus=this.statusFormControl.valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchAlarmStatus(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return this.searchText="",this.statusFormControl.patchValue("",{emitEvent:!0}),e}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e?e.alarmStatusList:null,[E.required]]})}displayStatus(e){return e?this.translate.instant(q.get(e)):void 0}fetchAlarmStatus(e){const t=this.getAlarmStatusList();if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(t.filter((t=>this.translate.instant(q.get(M[t])).toUpperCase().includes(e))))}return Ie(t)}alarmStatusSelected(e){this.addAlarmStatus(e.option.value),this.clear("")}removeAlarmStatus(e){const t=this.alarmStatusConfigForm.get("alarmStatusList").value;if(t){const n=t.indexOf(e);n>=0&&(t.splice(n,1),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}}addAlarmStatus(e){let t=this.alarmStatusConfigForm.get("alarmStatusList").value;t||(t=[]);-1===t.indexOf(e)&&(t.push(e),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}getAlarmStatusList(){return this.alarmStatusList.filter((e=>-1===this.alarmStatusConfigForm.get("alarmStatusList").value.indexOf(e)))}onAlarmStatusInputFocus(){this.statusFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.alarmStatusInput.nativeElement.value=e,this.statusFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.alarmStatusInput.nativeElement.blur(),this.alarmStatusInput.nativeElement.focus()}),0)}}e("CheckAlarmStatusComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Un,deps:[{token:A.Store},{token:_.TranslateService},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Un,selector:"tb-filter-node-check-alarm-status-config",viewQueries:[{propertyName:"alarmStatusInput",first:!0,predicate:["alarmStatusInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.UntypedFormBuilder}]},propDecorators:{alarmStatusInput:[{type:o,args:["alarmStatusInput",{static:!1}]}]}});class zn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.checkMessageConfigForm}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e?e.messageNames:null,[]],metadataNames:[e?e.metadataNames:null,[]],checkAllKeys:[!!e&&e.checkAllKeys,[]]})}validateConfig(){const e=this.checkMessageConfigForm.get("messageNames").value,t=this.checkMessageConfigForm.get("metadataNames").value;return e.length>0||t.length>0}removeMessageName(e){const t=this.checkMessageConfigForm.get("messageNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("messageNames").setValue(t,{emitEvent:!0}))}removeMetadataName(e){const t=this.checkMessageConfigForm.get("metadataNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("metadataNames").setValue(t,{emitEvent:!0}))}addMessageName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("messageNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("messageNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}addMetadataName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("metadataNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("metadataNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CheckMessageConfigComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zn,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class _n extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.keys(g),this.entitySearchDirectionTranslationsMap=y}configForm(){return this.checkRelationConfigForm}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[!!e&&e.checkForSingleEntity,[]],direction:[e?e.direction:null,[]],entityType:[e?e.entityType:null,e&&e.checkForSingleEntity?[E.required]:[]],entityId:[e?e.entityId:null,e&&e.checkForSingleEntity?[E.required]:[]],relationType:[e?e.relationType:null,[E.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[E.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[E.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_n,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_n,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:_e.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Ee.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","required","disabled","subscriptSizing"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class jn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=it,this.perimeterTypes=Object.keys(it),this.perimeterTypeTranslationMap=lt,this.rangeUnits=Object.keys(ut),this.rangeUnitTranslationMap=pt}configForm(){return this.geoFilterConfigForm}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[E.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[E.required]],perimeterType:[e?e.perimeterType:null,[E.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([E.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==it.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([])):(this.geoFilterConfigForm.get("centerLatitude").setValidators([E.required,E.min(-90),E.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([E.required,E.min(-180),E.max(180)]),this.geoFilterConfigForm.get("range").setValidators([E.required,E.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([E.required])),t||n!==it.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([E.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jn,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class $n extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e?e.messageTypes:null,[E.required]]})}}e("MessageTypeConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$n,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$n,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:un,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.TENANT,x.CUSTOMER,x.USER,x.DASHBOARD,x.RULE_CHAIN,x.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e?e.originatorTypes:null,[E.required]]})}}e("OriginatorTypeConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qn,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n
\n',dependencies:[{kind:"component",type:je.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","disabled","subscriptSizing","allowedEntityTypes","ignoreAuthorityFilter"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Jn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jn,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Yn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.switchConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",r=this.switchConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.switchConfigForm.get(t).setValue(e)}))}onValidate(){this.switchConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yn,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Wn{}e("RuleNodeCoreConfigFilterModule",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Wn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Wn,declarations:[zn,_n,jn,$n,Qn,Jn,Yn,Un],imports:[H,L,xn],exports:[zn,_n,jn,$n,Qn,Jn,Yn,Un]}),Wn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,decorators:[{type:l,args:[{declarations:[zn,_n,jn,$n,Qn,Jn,Yn,Un],imports:[H,L,xn],exports:[zn,_n,jn,$n,Qn,Jn,Yn,Un]}]}]});class Xn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=ot,this.originatorSources=Object.keys(ot),this.originatorSourceTranslationMap=at,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.USER,x.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[E.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===ot.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([E.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===ot.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([E.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xn,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fn,selector:"tb-relations-query-config-old",inputs:["disabled","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Zn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[E.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Zn,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",value:"false"},{name:"tb.mail-body-type.html",value:"true"},{name:"tb.mail-body-type.dynamic",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[E.required]],toTemplate:[e?e.toTemplate:null,[E.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[E.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null],bodyTemplate:[e?e.bodyTemplate:null,[E.required]]}),this.toEmailConfigForm.get("mailBodyType").valueChanges.pipe(ve([e?.subjectTemplate])).subscribe((e=>{"dynamic"===e?(this.toEmailConfigForm.get("isHtmlTemplate").patchValue("",{emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").setValidators(E.required)):this.toEmailConfigForm.get("isHtmlTemplate").clearValidators(),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity()}))}}e("ToEmailConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:er,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],keys:[e?e.keys:null,[E.required]]})}configForm(){return this.copyKeysConfigForm}removeKey(e){const t=this.copyKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.copyKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.copyKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.copyKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CopyKeysConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[E.required]]})}}e("RenameKeysConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[E.required]]})}}e("NodeJsonPathConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n",dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n"}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],keys:[e?e.keys:null,[E.required]]})}configForm(){return this.deleteKeysConfigForm}removeKey(e){const t=this.deleteKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteKeysConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class ar{}e("RulenodeCoreConfigTransformModule",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ar.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:ar,declarations:[Xn,Zn,er,tr,nr,rr,or],imports:[H,L,xn],exports:[Xn,Zn,er,tr,nr,rr,or]}),ar.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,decorators:[{type:l,args:[{declarations:[Xn,Zn,er,tr,nr,rr,or],imports:[H,L,xn],exports:[Xn,Zn,er,tr,nr,rr,or]}]}]});class ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=x}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[E.required]]})}}e("RuleChainInputComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ir,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:_e.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class lr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:lr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class sr{}e("RuleNodeCoreConfigFlowModule",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),sr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:sr,declarations:[ir,lr],imports:[H,L,xn],exports:[ir,lr]}),sr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,decorators:[{type:l,args:[{declarations:[ir,lr],imports:[H,L,xn],exports:[ir,lr]}]}]});class mr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{"create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","output-message-type":"Output message type","output-message-type-required":"Output message type is required","output-message-type-max-length":"Output message type should be less than 256","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. In case you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required!","limit-range":"Limit should be in a range from 2 to 1000!","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Time value should be in a range from 1 to 2147483647!","start-interval-value-required":"Start interval value is required!","end-interval-value-required":"End interval value is required!",filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Notify device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-hint":"If the message arrives from the device, we will push it back to the device by default.","notify-device-delete-hint":"Send notification about deleted attributes to device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","add-timeseries-key":"Add timeseries key","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Hint: use regular expression to copy keys by pattern",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","key-name":"Key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Max relation level should be greater than 0 or unspecified!","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required!","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required!","target-key":"Target key","target-key-required":"Target key is required!","attr-mapping-required":"At least one mapping entry should be specified!","fields-mapping":"Fields mapping*","fields-mapping-required":"At least one field mapping should be specified.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","source-field":"Source field","source-field-required":"Source field is required!","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","body-template":"Body Template","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","trim-double-quotes":"Message without quotes","trim-double-quotes-hint":"If selected, request body message payload will be sent without double quotes, i.e. msg = message body","read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Hint: Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Hint: Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Hint: Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required!","end-interval-required":"Interval end is required!","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"entity-details":"Select entity details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","entity-details-list-empty":"No entity details selected!","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-key-name":"Latitude key name","longitude-key-name":"Longitude key name","latitude-key-name-required":"Latitude key name is required.","longitude-key-name-required":"Longitude key name is required.","fetch-perimeter-info-from-message-metadata":"Fetch perimeter information from message metadata","perimeter-key-name":"Perimeter key name","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Please, use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required!","output-value-key":"Output value key","output-value-key-required":"Output value key is required!","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15!","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-cashing":"Use cashing","use-cashing-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required!","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time series","message-body-type":"Message body","message-metadata-type":"Message metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-type-field-input":"Type","argument-type-field-input-required":"Argument type is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Hint: use 0 to convert result to integer","add-to-body-field-input":"Add to message body","add-to-metadata-field-input":"Add to message metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Hint: specify a mathematical expression to evaluate. For example, transform Fahrenheit to Celsius using (x - 32) / 1.8)","retained-message":"Retained","attributes-mapping":"Attributes mapping*","latest-telemetry-mapping":"Latest telemetry mapping*","add-mapped-attribute-to":"Add mapped attributes to:","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to:","add-mapped-fields-to":"Add mapped fields to:","add-selected-details-to":"Add selected details to:","clear-selected-details":"Clear selected details","clear-selected-keys":"Clear selected keys","fetch-credentials-to":"Fetch credentials to:","add-originator-attributes-to":"Add originator attributes to:","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound message metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell Failure","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to:",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output message metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end")!',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch:","mapping-of-customers":"Mapping of customer's:",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to:","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's:","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required"},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping entry","add-entry":"Add entry","unique-key-value-pair-error":"'{{valText}}' must be different from the current '{{keyText}}'"},"mail-body-type":{"plain-text":"Plain Text",html:"HTML",dynamic:"Dynamic"}}},!0)}(e)}}e("RuleNodeCoreConfigModule",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,deps:[{token:_.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),mr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:mr,declarations:[$e],imports:[H,L],exports:[bn,Wn,qn,Bn,ar,sr,$e]}),mr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,imports:[H,L,bn,Wn,qn,Bn,ar,sr]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,decorators:[{type:l,args:[{declarations:[$e],imports:[H,L],exports:[bn,Wn,qn,Bn,ar,sr,$e]}]}],ctorParameters:function(){return[{type:_.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map +System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/platform-browser","@angular/material/select","@angular/material/core","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/icon","@angular/material/chips","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/material/tooltip","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","rxjs","@angular/material/expansion","@home/components/public-api","tslib","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@angular/material/slide-toggle","@home/components/relation/relation-filters.component","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@angular/material/button-toggle","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,u,p,d,c,f,g,y,x,b,h,C,v,F,L,k,T,I,N,S,q,M,A,G,E,D,V,w,P,R,O,H,K,B,U,z,_,j,$,Q,J,Y,W,X,Z,ee,te,ne,re,oe,ae,ie,le,se,me,ue,pe,de,ce,fe,ge,ye,xe,be,he,Ce,ve,Fe,Le,ke,Te,Ie,Ne,Se,qe,Me,Ae,Ge,Ee,De,Ve,we,Pe,Re,Oe,He,Ke,Be,Ue,ze,_e,je;return{setters:[function(e){t=e,n=e.Component,r=e.Pipe,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.NgModule},function(e){s=e.RuleNodeConfigurationComponent,m=e.AttributeScope,u=e.telemetryTypeTranslations,p=e.ServiceType,d=e.ScriptLanguage,c=e.AlarmSeverity,f=e.alarmSeverityTranslations,g=e.EntitySearchDirection,y=e.entitySearchDirectionTranslations,x=e.EntityType,b=e.PageComponent,h=e.coerceBoolean,C=e.MessageType,v=e.messageTypeNames,F=e,L=e.SharedModule,k=e.AggregationType,T=e.aggregationTranslations,I=e.NotificationType,N=e.SlackChanelType,S=e.SlackChanelTypesTranslateMap,q=e.alarmStatusTranslations,M=e.AlarmStatus},function(e){A=e},function(e){G=e,E=e.Validators,D=e.NgControl,V=e.NG_VALUE_ACCESSOR,w=e.NG_VALIDATORS,P=e.FormControl,R=e.UntypedFormControl},function(e){O=e,H=e.CommonModule},function(e){K=e},function(e){B=e},function(e){U=e},function(e){z=e},function(e){_=e},function(e){j=e},function(e){$=e},function(e){Q=e},function(e){J=e},function(e){Y=e.getCurrentAuthState,W=e,X=e.isDefinedAndNotNull,Z=e.isObject,ee=e.isNotEmptyStr},function(e){te=e},function(e){ne=e},function(e){re=e},function(e){oe=e.ENTER,ae=e.COMMA,ie=e.SEMICOLON},function(e){le=e},function(e){se=e},function(e){me=e},function(e){ue=e},function(e){pe=e.coerceBooleanProperty},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e},function(e){xe=e.tap,be=e.map,he=e.mergeMap,Ce=e.takeUntil,ve=e.startWith,Fe=e.share,Le=e.distinctUntilChanged},function(e){ke=e},function(e){Te=e},function(e){Ie=e.of,Ne=e.Subject},function(e){Se=e},function(e){qe=e.HomeComponentsModule},function(e){Me=e.__decorate},function(e){Ae=e},function(e){Ge=e},function(e){Ee=e},function(e){De=e},function(e){Ve=e},function(e){we=e},function(e){Pe=e},function(e){Re=e},function(e){Oe=e},function(e){He=e},function(e){Ke=e},function(e){Be=e},function(e){Ue=e},function(e){ze=e},function(e){_e=e},function(e){je=e}],execute:function(){class $e extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",$e),$e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$e,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qe{constructor(e){this.sanitizer=e}transform(e){return this.sanitizer.bypassSecurityTrustHtml(e)}}e("SafeHtmlPipe",Qe),Qe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,deps:[{token:j.DomSanitizer}],target:t.ɵɵFactoryTarget.Pipe}),Qe.ɵpipe=t.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Qe,name:"safeHtml"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,decorators:[{type:r,args:[{name:"safeHtml"}]}],ctorParameters:function(){return[{type:j.DomSanitizer}]}});class Je extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[E.required,E.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[E.required,E.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",Je),Je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Je,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Ye extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===m.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",Ye),Ye.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ye.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ye,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class We extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[E.required]]})}}e("CheckPointConfigComponent",We),We.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),We.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:We,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,decorators:[{type:n,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Xe extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[E.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===d.JS?[E.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===d.TBEL?[E.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.clearAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",r=this.clearAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.clearAlarmConfigForm.get(t).setValue(e)}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",Xe),Xe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xe,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Ze extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.alarmSeverities=Object.keys(c),this.alarmSeverityTranslationMap=f,this.separatorKeysCodes=[oe,ae,ie],this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([E.required]),this.createAlarmConfigForm.get("severity").setValidators([E.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==d.TBEL||this.tbelEnabled||(r=d.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===d.JS?[E.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===d.TBEL?[E.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.createAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",r=this.createAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.createAlarmConfigForm.get(t).setValue(e)}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",Ze),Ze.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ze,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ze.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ze,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ze,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class et extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[E.required]],entityType:[e?e.entityType:null,[E.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[E.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[E.required,E.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==x.DEVICE&&t!==x.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([E.required,E.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",et),et.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:et,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),et.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:et,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:et,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class tt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[E.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[E.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[E.required,E.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([E.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",tt),tt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,E.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,E.required]})}}e("DeviceProfileConfigComponent",nt),nt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class rt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[E.required,E.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[E.required,E.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(){const e=this.generatorConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",r=this.generatorConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.generatorConfigForm.get(t).setValue(e)}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}var ot;e("GeneratorConfigComponent",rt),rt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rt,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),rt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rt,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rt,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(ot||(ot={}));const at=new Map([[ot.CUSTOMER,"tb.rulenode.originator-customer"],[ot.TENANT,"tb.rulenode.originator-tenant"],[ot.RELATED,"tb.rulenode.originator-related"],[ot.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[ot.ENTITY,"tb.rulenode.originator-entity"]]);var it;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(it||(it={}));const lt=new Map([[it.CIRCLE,"tb.rulenode.perimeter-circle"],[it.POLYGON,"tb.rulenode.perimeter-polygon"]]);var st;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(st||(st={}));const mt=new Map([[st.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[st.SECONDS,"tb.rulenode.time-unit-seconds"],[st.MINUTES,"tb.rulenode.time-unit-minutes"],[st.HOURS,"tb.rulenode.time-unit-hours"],[st.DAYS,"tb.rulenode.time-unit-days"]]);var ut;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(ut||(ut={}));const pt=new Map([[ut.METER,"tb.rulenode.range-unit-meter"],[ut.KILOMETER,"tb.rulenode.range-unit-kilometer"],[ut.FOOT,"tb.rulenode.range-unit-foot"],[ut.MILE,"tb.rulenode.range-unit-mile"],[ut.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var dt,ct;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(dt||(dt={})),function(e){e.NAME="name",e.CREATED_TIME="createdTime",e.TYPE="type",e.FIRST_NAME="firstName",e.LAST_NAME="lastName",e.EMAIL="email",e.TITLE="title",e.COUNTRY="county",e.STATE="state",e.CITY="city",e.ADDRESS="address",e.ADDRESS2="address2",e.ZIP="zip",e.PHONE="phone",e.LABEL="label"}(ct||(ct={}));const ft=new Map([[ct.NAME,"tb.rulenode.name"],[ct.CREATED_TIME,"tb.rulenode.created-time"],[ct.TYPE,"tb.rulenode.type"],[ct.FIRST_NAME,"tb.rulenode.first-name"],[ct.LAST_NAME,"tb.rulenode.last-name"],[ct.EMAIL,"tb.rulenode.entity-details-email"],[ct.TITLE,"tb.rulenode.entity-details-title"],[ct.COUNTRY,"tb.rulenode.entity-details-country"],[ct.STATE,"tb.rulenode.entity-details-state"],[ct.CITY,"tb.rulenode.entity-details-city"],[ct.ADDRESS,"tb.rulenode.entity-details-address"],[ct.ADDRESS2,"tb.rulenode.entity-details-address2"],[ct.ZIP,"tb.rulenode.entity-details-zip"],[ct.PHONE,"tb.rulenode.entity-details-phone"],[ct.LABEL,"tb.rulenode.label"]]),gt=new Map([[dt.ID,"tb.rulenode.entity-details-id"],[dt.TITLE,"tb.rulenode.entity-details-title"],[dt.COUNTRY,"tb.rulenode.entity-details-country"],[dt.STATE,"tb.rulenode.entity-details-state"],[dt.CITY,"tb.rulenode.entity-details-city"],[dt.ZIP,"tb.rulenode.entity-details-zip"],[dt.ADDRESS,"tb.rulenode.entity-details-address"],[dt.ADDRESS2,"tb.rulenode.entity-details-address2"],[dt.PHONE,"tb.rulenode.entity-details-phone"],[dt.EMAIL,"tb.rulenode.entity-details-email"],[dt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var yt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(yt||(yt={}));const xt=new Map([[yt.FIRST,"tb.rulenode.first"],[yt.LAST,"tb.rulenode.last"],[yt.ALL,"tb.rulenode.all"]]);var bt,ht;!function(e){e.ASC="ASC",e.DESC="DESC"}(bt||(bt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(ht||(ht={}));const Ct=new Map([[bt.ASC,"tb.rulenode.ascending"],[bt.DESC,"tb.rulenode.descending"]]);var vt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(vt||(vt={}));const Ft=new Map([[vt.STANDARD,"tb.rulenode.sqs-queue-standard"],[vt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),Lt=["anonymous","basic","cert.PEM"],kt=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Tt=["sas","cert.PEM"],It=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var Nt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(Nt||(Nt={}));const St=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],qt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Mt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Mt||(Mt={}));const At=new Map([[Mt.CUSTOM,{value:Mt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Mt.ADD,{value:Mt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Mt.SUB,{value:Mt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Mt.MULT,{value:Mt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Mt.DIV,{value:Mt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Mt.SIN,{value:Mt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Mt.SINH,{value:Mt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Mt.COS,{value:Mt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Mt.COSH,{value:Mt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Mt.TAN,{value:Mt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Mt.TANH,{value:Mt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Mt.ACOS,{value:Mt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Mt.ASIN,{value:Mt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Mt.ATAN,{value:Mt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Mt.ATAN2,{value:Mt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Mt.EXP,{value:Mt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Mt.EXPM1,{value:Mt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Mt.SQRT,{value:Mt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Mt.CBRT,{value:Mt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Mt.GET_EXP,{value:Mt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Mt.HYPOT,{value:Mt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Mt.LOG,{value:Mt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Mt.LOG10,{value:Mt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Mt.LOG1P,{value:Mt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Mt.CEIL,{value:Mt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Mt.FLOOR,{value:Mt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Mt.FLOOR_DIV,{value:Mt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Mt.FLOOR_MOD,{value:Mt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Mt.ABS,{value:Mt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Mt.MIN,{value:Mt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Mt.MAX,{value:Mt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Mt.POW,{value:Mt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Mt.SIGNUM,{value:Mt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Mt.RAD,{value:Mt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Mt.DEG,{value:Mt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Gt,Et,Dt;!function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Gt||(Gt={})),function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Et||(Et={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(Dt||(Dt={}));const Vt=new Map([[Gt.ATTRIBUTE,"tb.rulenode.attribute-type"],[Gt.TIME_SERIES,"tb.rulenode.time-series-type"],[Gt.CONSTANT,"tb.rulenode.constant-type"],[Gt.MESSAGE_BODY,"tb.rulenode.message-body-type"],[Gt.MESSAGE_METADATA,"tb.rulenode.message-metadata-type"]]),wt=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var Pt,Rt;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(Pt||(Pt={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(Rt||(Rt={}));const Ot=new Map([[Pt.SHARED_SCOPE,"tb.rulenode.shared-scope"],[Pt.SERVER_SCOPE,"tb.rulenode.server-scope"],[Pt.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class Ht extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=it,this.perimeterTypes=Object.keys(it),this.perimeterTypeTranslationMap=lt,this.rangeUnits=Object.keys(ut),this.rangeUnitTranslationMap=pt,this.timeUnits=Object.keys(st),this.timeUnitsTranslationMap=mt}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[E.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[E.required]],perimeterType:[e?e.perimeterType:null,[E.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[E.required,E.min(1),E.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[E.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[E.required,E.min(1),E.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[E.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([E.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==it.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([E.required,E.min(-90),E.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([E.required,E.min(-180),E.max(180)]),this.geoActionConfigForm.get("range").setValidators([E.required,E.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([E.required])),t||n!==it.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([E.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",Ht),Ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ht,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Kt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.logConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",r=this.logConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.logConfigForm.get(t).setValue(e)}))}onValidate(){this.logConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",Kt),Kt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Kt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kt,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Bt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[E.required,E.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[E.required]]})}}e("MsgCountConfigComponent",Bt),Bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Bt,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Ut extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[E.required,E.min(1),E.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([E.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([E.required,E.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",Ut),Ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ut,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class zt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]]})}}e("PushToCloudConfigComponent",zt),zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zt,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class _t extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]]})}}e("PushToEdgeConfigComponent",_t),_t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_t,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",jt),jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jt,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class $t extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[E.required,E.min(0)]]})}}e("RpcRequestConfigComponent",$t),$t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$t,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required]],value:[e[n],[E.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[E.required]],value:["",[E.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Qt),Qt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qt,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:V,useExisting:a((()=>Qt)),multi:!0},{provide:w,useExisting:a((()=>Qt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:V,useExisting:a((()=>Qt)),multi:!0},{provide:w,useExisting:a((()=>Qt)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class Jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[E.required,E.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[E.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",Jt),Jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jt,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Yt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[E.required,E.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Yt),Yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yt,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Wt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[E.required,E.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[E.required,E.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Wt),Wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Wt,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Xt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]],keys:[e?e.keys:null,[E.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",Xt),Xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xt,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Zt extends b{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup())}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=At,this.ArgumentType=Gt,this.attributeScopeMap=Ot,this.argumentTypeResultMap=Vt,this.arguments=Object.values(Gt),this.attributeScope=Object.values(Pt),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.argumentsFormGroup=this.fb.group({}),this.argumentsFormGroup.addControl("arguments",this.fb.array([])),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray(),n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):this.argumentsFormGroup.enable({emitEvent:!1})}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()));const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t)),this.setupArgumentsFormGroup(),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()})))}removeArgument(e){this.argumentsFormGroup.get("arguments").removeAt(e),this.updateArgumentNames()}addArgument(){const e=this.argumentsFormGroup.get("arguments"),t=this.createArgumentControl(null,e.length);e.push(t)}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Mt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([E.minLength(this.minArgs),E.maxLength(this.maxArgs)]),this.argumentsFormGroup.get("arguments").value.length>this.maxArgs&&(this.argumentsFormGroup.get("arguments").controls.length=this.maxArgs);this.argumentsFormGroup.get("arguments").value.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!0}),n.get("defaultValue").updateValueAndValidity({emitEvent:!0})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Gt.ATTRIBUTE?e.get("attributeScope").enable():e.get("attributeScope").disable(),t&&t!==Gt.CONSTANT?e.get("defaultValue").enable():e.get("defaultValue").disable()}updateArgumentNames(){this.argumentsFormGroup.get("arguments").controls.forEach(((e,t)=>{e.get("name").setValue(wt[t])}))}updateModel(){const e=this.argumentsFormGroup.get("arguments").value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Zt),Zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Zt,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:V,useExisting:a((()=>Zt)),multi:!0},{provide:w,useExisting:a((()=>Zt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"],dependencies:[{kind:"directive",type:O.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ge.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:ge.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:ye.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:ye.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:ye.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:V,useExisting:a((()=>Zt)),multi:!0},{provide:w,useExisting:a((()=>Zt)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class en extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...At.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(xe((e=>{let t;t="string"==typeof e&&Mt[e]?Mt[e]:null,this.updateView(t)})),be((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=At.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",en),en.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:en,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),en.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:en,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:V,useExisting:a((()=>en)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:en,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:V,useExisting:a((()=>en)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Mt,this.ArgumentTypeResult=Et,this.argumentTypeResultMap=Vt,this.attributeScopeMap=Ot,this.argumentsResult=Object.values(Et),this.attributeScopeResult=Object.values(Rt)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[E.required]],arguments:[e?e.arguments:null,[E.required]],customFunction:[e?e.customFunction:"",[E.required]],result:this.fb.group({type:[e?e.result.type:null,[E.required]],attributeScope:[e?e.result.attributeScope:null],key:[e?e.result.key:"",[E.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result").get("type").value;t===Mt.CUSTOM?this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Et.ATTRIBUTE?this.mathFunctionConfigForm.get("result").get("attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result").get("attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result").get("attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",tn),tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tn,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Zt,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:en,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tn,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nn{constructor(e,t){this.store=e,this.fb=t,this.subscriptSizing="fixed",this.searchText="",this.dirty=!1,this.messageTypes=["POST_ATTRIBUTES_REQUEST","POST_TELEMETRY_REQUEST"],this.propagateChange=e=>{},this.messageTypeFormGroup=this.fb.group({messageType:[null,[E.required,E.maxLength(255)]]})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.outputMessageTypes=this.messageTypeFormGroup.get("messageType").valueChanges.pipe(xe((e=>{this.updateView(e)})),be((e=>e||"")),he((e=>this.fetchMessageTypes(e))))}writeValue(e){this.searchText="",this.modelValue=e,this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1}),this.dirty=!0}onFocus(){this.dirty&&(this.messageTypeFormGroup.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0}),this.dirty=!1)}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}displayMessageTypeFn(e){return e||void 0}fetchMessageTypes(e,t=!1){return this.searchText=e,Ie(this.messageTypes).pipe(be((n=>n.filter((n=>t?!!e&&n===e:!e||n.toUpperCase().startsWith(e.toUpperCase()))))))}clear(){this.messageTypeFormGroup.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}}e("OutputMessageTypeAutocompleteComponent",nn),nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nn,selector:"tb-output-message-type-autocomplete",inputs:{autocompleteHint:"autocompleteHint",subscriptSizing:"subscriptSizing"},providers:[{provide:V,useExisting:a((()=>nn)),multi:!0}],viewQueries:[{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0,static:!0}],ngImport:t,template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:V,useExisting:a((()=>nn)),multi:!0}],template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{messageTypeInput:[{type:o,args:["messageTypeInput",{static:!0}]}],autocompleteHint:[{type:i}],subscriptSizing:[{type:i}]}});class rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.destroy$=new Ne,this.serviceType=p.TB_RULE_ENGINE,this.deduplicationStrategie=yt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=xt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[X(e?.interval)?e.interval:null,[E.required,E.min(1)]],strategy:[X(e?.strategy)?e.strategy:null,[E.required]],outMsgType:[X(e?.outMsgType)?e.outMsgType:null,[E.required]],queueName:[X(e?.queueName)?e.queueName:null,[E.required]],maxPendingMsgs:[X(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[E.required,E.min(1),E.max(1e3)]],maxRetries:[X(e?.maxRetries)?e.maxRetries:null,[E.required,E.min(0),E.max(100)]]}),this.deduplicationConfigForm.get("strategy").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.enableControl(e)}))}updateValidators(e){this.enableControl(this.deduplicationConfigForm.get("strategy").value)}validatorTriggers(){return["strategy"]}enableControl(e){e===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("DeduplicationConfigComponent",rn),rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rn,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:nn,selector:"tb-output-message-type-autocomplete",inputs:["autocompleteHint","subscriptSizing"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class on extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[e[n],[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",on),on.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:on,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),on.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:on,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:V,useExisting:a((()=>on)),multi:!0},{provide:w,useExisting:a((()=>on)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n {{ hintText }}\n \n
\n
\n
\n \n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),Me([h()],on.prototype,"disabled",void 0),Me([h()],on.prototype,"uniqueKeyValuePairValidator",void 0),Me([h()],on.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:on,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:V,useExisting:a((()=>on)),multi:!0},{provide:w,useExisting:a((()=>on)),multi:!0}],template:'
\n
\n \n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n {{ hintText }}\n \n
\n
\n
\n \n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class an{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne}ngOnInit(){this.slideToggleControlGroup=this.fb.group({slideToggleControl:[null,[]]}),this.slideToggleControlGroup.get("slideToggleControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.slideToggleControlGroup.get("slideToggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SlideToggleComponent",an),an.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:an,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),an.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:an,selector:"tb-slide-toggle",inputs:{slideToggleName:"slideToggleName",slideToggleTooltip:"slideToggleTooltip"},providers:[{provide:V,useExisting:a((()=>an)),multi:!0}],ngImport:t,template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"],dependencies:[{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:De.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:an,decorators:[{type:n,args:[{selector:"tb-slide-toggle",providers:[{provide:V,useExisting:a((()=>an)),multi:!0}],template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{slideToggleName:[{type:i}],slideToggleTooltip:[{type:i}]}});class ln extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[E.min(1)]],relationType:[null],deviceTypes:[null,[E.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",ln),ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ln,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ln,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>ln)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ge.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["label","required","disabled","entityType"]},{kind:"component",type:Ee.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","required","disabled","subscriptSizing"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ln,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:V,useExisting:a((()=>ln)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class sn{set required(e){this.requiredValue=pe(e)}get required(){return this.requiredValue}}e("FieldsetComponent",sn),sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sn,deps:[],target:t.ɵɵFactoryTarget.Component}),sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:sn,selector:"tb-fieldset-component",inputs:{label:"label",required:"required"},ngImport:t,template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sn,decorators:[{type:n,args:[{selector:"tb-fieldset-component",template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],propDecorators:{label:[{type:i}],required:[{type:i}]}});class mn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[E.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",mn),mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:mn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>mn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ve.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:V,useExisting:a((()=>mn)),multi:!0}],template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class un extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.message-type",this.separatorKeysCodes=[oe,ae,ie],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(C))this.messageTypesList.push({name:v.get(C[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchMessageTypes(e))),Fe())}ngAfterViewInit(){}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return!!(e&&null!=e&&e.length>0)}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ie(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t=null;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:un,deps:[{token:A.Store},{token:_.TranslateService},{token:F.TruncatePipe},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:un,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:V,useExisting:a((()=>un)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:V,useExisting:a((()=>un)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:F.TruncatePipe},{type:G.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class pn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRquired=!0,this.allCredentialsTypes=Lt,this.credentialsTypeTranslationsMap=kt,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[E.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.pipe(Le()).subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){X(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators(!1))}setDisabledState(e){e?this.credentialsConfigFormGroup.disable():(this.credentialsConfigFormGroup.enable(),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([E.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRquired?[E.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(E.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",pn),pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:pn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRquired:"passwordFieldRquired"},providers:[{provide:V,useExisting:a((()=>pn)),multi:!0},{provide:w,useExisting:a((()=>pn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:O.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:O.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Se.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:V,useExisting:a((()=>pn)),multi:!0},{provide:w,useExisting:a((()=>pn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRquired:[{type:i}]}});class dn{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne,this.fetchTo=Dt}ngOnInit(){this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("MsgMetadataChipComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:dn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText"},providers:[{provide:V,useExisting:a((()=>dn)),multi:!0}],ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.message\' | translate }}\n {{ \'tb.rulenode.metadata\' | translate }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"],dependencies:[{kind:"component",type:se.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:se.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:V,useExisting:a((()=>dn)),multi:!0}],template:'
\n \n \n {{ \'tb.rulenode.message\' | translate }}\n {{ \'tb.rulenode.metadata\' | translate }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{labelText:[{type:i}]}});class cn extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new Ne,this.sourceFieldSubcritption=[],this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({}),this.svListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required]],value:[e[n],[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.svListFormGroup.setControl("keyVals",this.fb.array(t));for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e);this.valueChangeSubscription=this.svListFormGroup.valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.updateModel()}))}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value)t.push(this.selectOptions.find((t=>t===e.key)));const n=[];for(const r of this.selectOptions)X(t.find((e=>e===r)))&&r!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.svListFormGroup.get("keyVals").removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){const e=this.svListFormGroup.get("keyVals");e.push(this.fb.group({key:["",[E.required]],value:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(e.controls[e.length-1])}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(Ce(this.destroy$)).subscribe((t=>{e.get("value").patchValue(this.targetKeyPrefix+t[0].toUpperCase()+t.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cn,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:cn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",selectOptionsTranslate:"selectOptionsTranslate",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:V,useExisting:a((()=>cn)),multi:!0},{provide:w,useExisting:a((()=>cn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n \n {{ selectText }}\n \n \n {{selectOptionsTranslate.get(option) | translate}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n {{ hintText }}\n \n
\n
\n
\n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),Me([h()],cn.prototype,"disabled",void 0),Me([h()],cn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:V,useExisting:a((()=>cn)),multi:!0},{provide:w,useExisting:a((()=>cn)),multi:!0}],template:'
\n
\n \n
\n
\n
\n \n {{ selectText }}\n \n \n {{selectOptionsTranslate.get(option) | translate}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n {{ hintText }}\n \n
\n
\n
\n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],selectOptionsTranslate:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class fn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:fn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>fn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ve.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:V,useExisting:a((()=>fn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class gn{set enableFieldToggle(e){this._enableFieldToggle=pe(e)}get enableFieldToggle(){return this._enableFieldToggle}constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne,this.DataToFetch=ht}ngOnInit(){this.toggleControlGroup=this.fb.group({toggleControl:[null,[]]}),this.toggleControlGroup.get("toggleControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.toggleControlGroup.get("toggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("FetchToDataToggleComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:gn,selector:"tb-fetch-to-data-toggle",inputs:{enableFieldToggle:"enableFieldToggle"},providers:[{provide:V,useExisting:a((()=>gn)),multi:!0}],ngImport:t,template:'
\n \n {{ \'tb.rulenode.attributes\' | translate }}\n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n {{ \'tb.rulenode.fields\' | translate }}\n \n
\n',styles:[":host ::ng-deep{margin-bottom:12px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;width:215px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Re.MatButtonToggleGroup,selector:"mat-button-toggle-group",inputs:["appearance","name","vertical","value","multiple","disabled"],outputs:["valueChange","change"],exportAs:["matButtonToggleGroup"]},{kind:"component",type:Re.MatButtonToggle,selector:"mat-button-toggle",inputs:["disableRipple","aria-label","aria-labelledby","id","name","value","tabIndex","appearance","checked","disabled"],outputs:["change"],exportAs:["matButtonToggle"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-fetch-to-data-toggle",providers:[{provide:V,useExisting:a((()=>gn)),multi:!0}],template:'
\n \n {{ \'tb.rulenode.attributes\' | translate }}\n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n {{ \'tb.rulenode.fields\' | translate }}\n \n
\n',styles:[":host ::ng-deep{margin-bottom:12px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;width:215px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{enableFieldToggle:[{type:i}]}});class yn{constructor(e,t,n){this.store=e,this.translate=t,this.fb=n,this.destroy$=new Ne,this.separatorKeysCodes=[oe,ae,ie]}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[null,[]],sharedAttributeNames:[null,[]],serverAttributeNames:[null,[]],latestTsKeyNames:[null,[]],getLatestValueWithTs:[!1,[]]}),this.attributeControlGroup.valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.attributeControlGroup.patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}removeKey(e,t){const n=this.attributeControlGroup.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.attributeControlGroup.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.attributeControlGroup.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.attributeControlGroup.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}clearChipGrid(e){this.attributeControlGroup.get(e).patchValue([],{emitEvent:!0})}}e("SelectAttributesComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:yn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:V,useExisting:a((()=>yn)),multi:!0}],ngImport:t,template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin:10px 0 12px;display:block}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:V,useExisting:a((()=>yn)),multi:!0}],template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin:10px 0 12px;display:block}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class xn{}e("RulenodeCoreConfigCommonModule",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),xn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:xn,declarations:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn],imports:[H,L,qe],exports:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn]}),xn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,imports:[H,L,qe]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,decorators:[{type:l,args:[{declarations:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn],imports:[H,L,qe],exports:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn]}]}]});class bn{}e("RuleNodeCoreConfigActionModule",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),bn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:bn,declarations:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn],imports:[H,L,qe,xn],exports:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn]}),bn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,imports:[H,L,qe,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,decorators:[{type:l,args:[{declarations:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn],imports:[H,L,qe,xn],exports:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn]}]}]});class hn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[E.min(0),E.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:X(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:X(e?.outputValueKey)?e.outputValueKey:null,useCache:!X(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!X(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:X(e?.periodValueKey)?e.periodValueKey:null,round:X(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!X(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return e.inputValueKey=e.inputValueKey.trim(),e.outputValueKey=e.outputValueKey.trim(),e}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([E.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:hn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Cn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n].trim();return e.dataMapping=t,e}prepareInputConfig(e){let t,n;return t=X(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Cn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class vn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[E.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return Z(e)&&(e.attributesControl={clientAttributeNames:X(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:X(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:X(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!X(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:X(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!X(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:vn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ln,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:yn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Fn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.entityDetailsTranslationsMap=gt,this.entityDetailsList=[],this.searchText="",this.displayDetailsFn=this.displayDetails.bind(this);for(const e of Object.keys(dt))this.entityDetailsList.push(dt[e]);this.detailsFormControl=new P(""),this.filteredEntityDetails=this.detailsFormControl.valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchEntityDetails(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return this.searchText="",this.detailsFormControl.patchValue("",{emitEvent:!0}),this.detailsList=e?e.detailsList:[],t=X(e?.addToMetadata)?e.addToMetadata?Dt.METADATA:Dt.DATA:e?.fetchTo?e.fetchTo:Dt.DATA,{detailsList:X(e?.detailsList)?e.detailsList:null,fetchTo:t}}prepareOutputConfig(e){return e.detailsList=this.detailsList,e}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[E.required]],fetchTo:[e.fetchTo,[]]}),this.detailsList=e?e.detailsList:[]}displayDetails(e){return e?this.translate.instant(gt.get(e)):void 0}fetchEntityDetails(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(this.entityDetailsList.filter((t=>this.translate.instant(gt.get(dt[t])).toUpperCase().includes(e))))}return Ie(this.entityDetailsList)}detailsFieldSelected(e){this.addDetailsField(e.option.value),this.clear("")}removeDetailsField(e){const t=this.detailsList.indexOf(e);t>=0&&(this.detailsList.splice(t,1),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}addDetailsField(e){this.detailsList||(this.detailsList=[]);-1===this.detailsList.indexOf(e)&&(this.detailsList.push(e),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}onEntityDetailsInputFocus(){this.detailsFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clearChipGrid(){this.detailsList=[],this.entityDetailsConfigForm.get("detailsList").patchValue([],{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}clear(e=""){this.detailsInput.nativeElement.value=e,this.detailsFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}}e("EntityDetailsConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Fn,selector:"tb-enrichment-node-entity-details-config",viewQueries:[{propertyName:"detailsInput",first:!0,predicate:["detailsInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]},propDecorators:{detailsInput:[{type:o,args:["detailsInput",{static:!1}]}]}});class Ln extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[oe,ae,ie],this.aggregationTypes=k,this.aggregations=Object.keys(k),this.aggregationTypesTranslations=T,this.fetchMode=yt,this.fetchModes=Object.keys(yt),this.deduplicationStrategiesTranslations=xt,this.samplingOrders=Object.keys(bt),this.samplingOrdersTranslate=Ct,this.timeUnits=Object.values(st),this.timeUnitsTranslationMap=mt,this.timeUnitMap={[st.MILLISECONDS]:1,[st.SECONDS]:1e3,[st.MINUTES]:6e4,[st.HOURS]:36e5,[st.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[]],aggregation:[e.aggregation,[E.required]],fetchMode:[e.fetchMode,[E.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,e.startIntervalPattern=e.startIntervalPattern.trim(),e.endIntervalPattern=e.endIntervalPattern.trim(),delete e.interval,e}prepareInputConfig(e){return Z(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:X(e?.aggregation)?e.aggregation:k.NONE,fetchMode:X(e?.fetchMode)?e.fetchMode:yt.FIRST,orderBy:X(e?.orderBy)?e.orderBy:bt.ASC,limit:X(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!X(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:X(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:X(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:st.MINUTES,endInterval:X(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:X(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:st.MINUTES},startIntervalPattern:X(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:X(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===yt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([E.required,E.min(2),E.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([E.required,E.min(1),E.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([E.required,E.min(1),E.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}fetchModeHintSelector(){let e;switch(this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value){case yt.ALL:e="tb.rulenode.all-mode-hint";break;case yt.LAST:e="tb.rulenode.last-mode-hint";break;case yt.FIRST:e="tb.rulenode.first-mode-hint"}return e}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}}e("GetTelemetryFromDatabaseConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ln,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ln,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n {{ deduplicationStrategiesTranslations.get(fetchMode) | translate}}\n \n
\n {{ fetchModeHintSelector() | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle mat-button-toggle{width:215px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .additional-inputs{margin-bottom:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:Re.MatButtonToggleGroup,selector:"mat-button-toggle-group",inputs:["appearance","name","vertical","value","multiple","disabled"],outputs:["valueChange","change"],exportAs:["matButtonToggleGroup"]},{kind:"component",type:Re.MatButtonToggle,selector:"mat-button-toggle",inputs:["disableRipple","aria-label","aria-labelledby","id","name","value","tabIndex","appearance","checked","disabled"],outputs:["change"],exportAs:["matButtonToggle"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n {{ deduplicationStrategiesTranslations.get(fetchMode) | translate}}\n \n
\n {{ fetchModeHintSelector() | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle mat-button-toggle{width:215px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .additional-inputs{margin-bottom:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class kn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return Z(e)&&(e.attributesControl={clientAttributeNames:X(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:X(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:X(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!X(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA,tellFailureIfAbsent:!!X(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:X(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:kn,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:yn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorFields=[],this.originatorFieldsTranslations=ft;for(const e of Object.keys(ct))this.originatorFields.push(ct[e])}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){for(const t of Object.keys(e.dataMapping))e.dataMapping[t]=e.dataMapping[t].trim();return e}prepareInputConfig(e){return{dataMapping:X(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:X(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[E.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Tn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:cn,selector:"tb-sv-map-config",inputs:["selectOptions","selectOptionsTranslate","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class In extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht,this.originatorFieldsTranslations=ft,this.originatorFields=[],this.destroy$=new Ne,this.defaultKvMap={serialNumber:"sn"},this.defaultSvMap={name:"relatedEntityName"},this.dataToFetchPrevValue="";for(const e of Object.keys(ct))this.originatorFields.push(ct[e])}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n].trim();return e.dataMapping=t,e}prepareInputConfig(e){let t;return X(e?.telemetry)?this.dataToFetchPrevValue=e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:this.dataToFetchPrevValue=X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,t=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{relationsQuery:X(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:this.dataToFetchPrevValue,dataMapping:t,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[E.required]],dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo,[]]}),this.relatedAttributesConfigForm.get("dataToFetch").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{e===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultSvMap,{emitEvent:!1}),e!==ht.FIELDS&&this.dataToFetchPrevValue===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultKvMap,{emitEvent:!1}),this.dataToFetchPrevValue=e}))}msgMetadataChipLabel(){switch(this.relatedAttributesConfigForm.get("dataToFetch").value){case ht.ATTRIBUTES:return"tb.rulenode.add-mapped-attribute-to";case ht.LATEST_TELEMETRY:return"tb.rulenode.add-mapped-latest-telemetry-to";case ht.FIELDS:return"tb.rulenode.add-mapped-fields-to"}}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("RelatedAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:In,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:In,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:mn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:cn,selector:"tb-sv-map-config",inputs:["selectOptions","selectOptionsTranslate","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Nn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=X(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Nn,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Sn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Sn,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class qn{}e("RulenodeCoreConfigEnrichmentModule",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),qn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:qn,declarations:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn],imports:[H,L,xn],exports:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn]}),qn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,decorators:[{type:l,args:[{declarations:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn],imports:[H,L,xn],exports:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn]}]}]});class Mn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Tt,this.azureIotHubCredentialsTypeTranslationsMap=It}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[E.required,E.min(1),E.max(200)]],clientId:[e?e.clientId:null,[E.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[E.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([E.required]);break;case"cert.PEM":t.get("privateKey").setValidators([E.required]),t.get("privateKeyFileName").setValidators([E.required]),t.get("cert").setValidators([E.required]),t.get("certFileName").setValidators([E.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Mn,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:O.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:O.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Se.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class An extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=St,this.ToByteStandartCharsetTypeTranslationMap=qt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[E.required]],retries:[e?e.retries:null,[E.min(0)]],batchSize:[e?e.batchSize:null,[E.min(0)]],linger:[e?e.linger:null,[E.min(0)]],bufferMemory:[e?e.bufferMemory:null,[E.min(0)]],acks:[e?e.acks:null,[E.required]],keySerializer:[e?e.keySerializer:null,[E.required]],valueSerializer:[e?e.valueSerializer:null,[E.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([E.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:An,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:An,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Gn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[]}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[E.required,E.min(1),E.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ee(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]}),this.subscriptions.push(this.mqttConfigForm.get("clientId").valueChanges.subscribe((e=>{ee(e)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1})})))}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}}e("MqttConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Gn,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:pn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRquired"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class En extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=I,this.entityType=x}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[E.required]],targets:[e?e.targets:[],[E.required]]})}}e("NotificationConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:En,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:En,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:Oe.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:He.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","disabled","notificationTypes"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Dn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[E.required]],topicName:[e?e.topicName:null,[E.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[E.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[E.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Dn,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Vn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[E.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[E.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Vn,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class wn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(Nt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[E.required]],requestMethod:[e?e.requestMethod:null,[E.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],trimDoubleQuotes:[!!e&&e.trimDoubleQuotes,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[E.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[E.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[E.required,E.min(1),E.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([E.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([E.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",wn),wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:wn,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:pn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRquired"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wn,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Pn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([E.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([E.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([E.required,E.min(1),E.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([E.required,E.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[E.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[E.required,E.min(1),E.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",Pn),Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Pn,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ke.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pn,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[E.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[E.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([E.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Rn,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Be.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class On extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(N),this.slackChanelTypesTranslateMap=S}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[E.required]],conversationType:[e?e.conversationType:null,[E.required]],conversation:[e?e.conversation:null,[E.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([E.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:On,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:On,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ze.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Hn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[E.required]],accessKeyId:[e?e.accessKeyId:null,[E.required]],secretAccessKey:[e?e.secretAccessKey:null,[E.required]],region:[e?e.region:null,[E.required]]})}}e("SnsConfigComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Hn,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Kn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=vt,this.sqsQueueTypes=Object.keys(vt),this.sqsQueueTypeTranslationsMap=Ft}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[E.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[E.required]],delaySeconds:[e?e.delaySeconds:null,[E.min(0),E.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[E.required]],secretAccessKey:[e?e.secretAccessKey:null,[E.required]],region:[e?e.region:null,[E.required]]})}}e("SqsConfigComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kn,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Bn{}e("RulenodeCoreConfigExternalModule",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Bn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Bn,declarations:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On],imports:[H,L,qe,xn],exports:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On]}),Bn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,imports:[H,L,qe,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,decorators:[{type:l,args:[{declarations:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On],imports:[H,L,qe,xn],exports:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On]}]}]});class Un extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.alarmStatusTranslationsMap=q,this.alarmStatusList=[],this.searchText="",this.displayStatusFn=this.displayStatus.bind(this);for(const e of Object.keys(M))this.alarmStatusList.push(M[e]);this.statusFormControl=new R(""),this.filteredAlarmStatus=this.statusFormControl.valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchAlarmStatus(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return this.searchText="",this.statusFormControl.patchValue("",{emitEvent:!0}),e}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e?e.alarmStatusList:null,[E.required]]})}displayStatus(e){return e?this.translate.instant(q.get(e)):void 0}fetchAlarmStatus(e){const t=this.getAlarmStatusList();if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(t.filter((t=>this.translate.instant(q.get(M[t])).toUpperCase().includes(e))))}return Ie(t)}alarmStatusSelected(e){this.addAlarmStatus(e.option.value),this.clear("")}removeAlarmStatus(e){const t=this.alarmStatusConfigForm.get("alarmStatusList").value;if(t){const n=t.indexOf(e);n>=0&&(t.splice(n,1),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}}addAlarmStatus(e){let t=this.alarmStatusConfigForm.get("alarmStatusList").value;t||(t=[]);-1===t.indexOf(e)&&(t.push(e),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}getAlarmStatusList(){return this.alarmStatusList.filter((e=>-1===this.alarmStatusConfigForm.get("alarmStatusList").value.indexOf(e)))}onAlarmStatusInputFocus(){this.statusFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.alarmStatusInput.nativeElement.value=e,this.statusFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.alarmStatusInput.nativeElement.blur(),this.alarmStatusInput.nativeElement.focus()}),0)}}e("CheckAlarmStatusComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Un,deps:[{token:A.Store},{token:_.TranslateService},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Un,selector:"tb-filter-node-check-alarm-status-config",viewQueries:[{propertyName:"alarmStatusInput",first:!0,predicate:["alarmStatusInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.UntypedFormBuilder}]},propDecorators:{alarmStatusInput:[{type:o,args:["alarmStatusInput",{static:!1}]}]}});class zn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.checkMessageConfigForm}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e?e.messageNames:null,[]],metadataNames:[e?e.metadataNames:null,[]],checkAllKeys:[!!e&&e.checkAllKeys,[]]})}validateConfig(){const e=this.checkMessageConfigForm.get("messageNames").value,t=this.checkMessageConfigForm.get("metadataNames").value;return e.length>0||t.length>0}removeMessageName(e){const t=this.checkMessageConfigForm.get("messageNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("messageNames").setValue(t,{emitEvent:!0}))}removeMetadataName(e){const t=this.checkMessageConfigForm.get("metadataNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("metadataNames").setValue(t,{emitEvent:!0}))}addMessageName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("messageNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("messageNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}addMetadataName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("metadataNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("metadataNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CheckMessageConfigComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zn,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class _n extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.keys(g),this.entitySearchDirectionTranslationsMap=y}configForm(){return this.checkRelationConfigForm}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[!!e&&e.checkForSingleEntity,[]],direction:[e?e.direction:null,[]],entityType:[e?e.entityType:null,e&&e.checkForSingleEntity?[E.required]:[]],entityId:[e?e.entityId:null,e&&e.checkForSingleEntity?[E.required]:[]],relationType:[e?e.relationType:null,[E.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[E.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[E.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_n,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_n,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:_e.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Ee.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","required","disabled","subscriptSizing"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class jn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=it,this.perimeterTypes=Object.keys(it),this.perimeterTypeTranslationMap=lt,this.rangeUnits=Object.keys(ut),this.rangeUnitTranslationMap=pt}configForm(){return this.geoFilterConfigForm}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[E.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[E.required]],perimeterType:[e?e.perimeterType:null,[E.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([E.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==it.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([])):(this.geoFilterConfigForm.get("centerLatitude").setValidators([E.required,E.min(-90),E.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([E.required,E.min(-180),E.max(180)]),this.geoFilterConfigForm.get("range").setValidators([E.required,E.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([E.required])),t||n!==it.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([E.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jn,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class $n extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e?e.messageTypes:null,[E.required]]})}}e("MessageTypeConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$n,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$n,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:un,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.TENANT,x.CUSTOMER,x.USER,x.DASHBOARD,x.RULE_CHAIN,x.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e?e.originatorTypes:null,[E.required]]})}}e("OriginatorTypeConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qn,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n
\n',dependencies:[{kind:"component",type:je.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","disabled","subscriptSizing","allowedEntityTypes","ignoreAuthorityFilter"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Jn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jn,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Yn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.switchConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",r=this.switchConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.switchConfigForm.get(t).setValue(e)}))}onValidate(){this.switchConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yn,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Wn{}e("RuleNodeCoreConfigFilterModule",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Wn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Wn,declarations:[zn,_n,jn,$n,Qn,Jn,Yn,Un],imports:[H,L,xn],exports:[zn,_n,jn,$n,Qn,Jn,Yn,Un]}),Wn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,decorators:[{type:l,args:[{declarations:[zn,_n,jn,$n,Qn,Jn,Yn,Un],imports:[H,L,xn],exports:[zn,_n,jn,$n,Qn,Jn,Yn,Un]}]}]});class Xn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=ot,this.originatorSources=Object.keys(ot),this.originatorSourceTranslationMap=at,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.USER,x.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[E.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===ot.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([E.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===ot.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([E.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xn,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fn,selector:"tb-relations-query-config-old",inputs:["disabled","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Zn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[E.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Zn,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",value:"false"},{name:"tb.mail-body-type.html",value:"true"},{name:"tb.mail-body-type.dynamic",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[E.required]],toTemplate:[e?e.toTemplate:null,[E.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[E.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null],bodyTemplate:[e?e.bodyTemplate:null,[E.required]]}),this.toEmailConfigForm.get("mailBodyType").valueChanges.pipe(ve([e?.subjectTemplate])).subscribe((e=>{"dynamic"===e?(this.toEmailConfigForm.get("isHtmlTemplate").patchValue("",{emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").setValidators(E.required)):this.toEmailConfigForm.get("isHtmlTemplate").clearValidators(),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity()}))}}e("ToEmailConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:er,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],keys:[e?e.keys:null,[E.required]]})}configForm(){return this.copyKeysConfigForm}removeKey(e){const t=this.copyKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.copyKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.copyKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.copyKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CopyKeysConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[E.required]]})}}e("RenameKeysConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[E.required]]})}}e("NodeJsonPathConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n",dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n"}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],keys:[e?e.keys:null,[E.required]]})}configForm(){return this.deleteKeysConfigForm}removeKey(e){const t=this.deleteKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteKeysConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class ar{}e("RulenodeCoreConfigTransformModule",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ar.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:ar,declarations:[Xn,Zn,er,tr,nr,rr,or],imports:[H,L,xn],exports:[Xn,Zn,er,tr,nr,rr,or]}),ar.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,decorators:[{type:l,args:[{declarations:[Xn,Zn,er,tr,nr,rr,or],imports:[H,L,xn],exports:[Xn,Zn,er,tr,nr,rr,or]}]}]});class ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=x}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[E.required]]})}}e("RuleChainInputComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ir,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:_e.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class lr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:lr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class sr{}e("RuleNodeCoreConfigFlowModule",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),sr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:sr,declarations:[ir,lr],imports:[H,L,xn],exports:[ir,lr]}),sr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,decorators:[{type:l,args:[{declarations:[ir,lr],imports:[H,L,xn],exports:[ir,lr]}]}]});class mr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{"create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","output-message-type":"Output message type","output-message-type-required":"Output message type is required","output-message-type-max-length":"Output message type should be less than 256","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. In case you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required!","limit-range":"Limit should be in a range from 2 to 1000!","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Time value should be in a range from 1 to 2147483647!","start-interval-value-required":"Start interval value is required!","end-interval-value-required":"End interval value is required!",filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Notify device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-hint":"If the message arrives from the device, we will push it back to the device by default.","notify-device-delete-hint":"Send notification about deleted attributes to device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","add-timeseries-key":"Add timeseries key","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Hint: use regular expression to copy keys by pattern",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","key-name":"Key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Max relation level should be greater than 0 or unspecified!","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required!","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required!","target-key":"Target key","target-key-required":"Target key is required!","attr-mapping-required":"At least one mapping entry should be specified!","fields-mapping":"Fields mapping*","fields-mapping-required":"At least one field mapping should be specified.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","source-field":"Source field","source-field-required":"Source field is required!","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","body-template":"Body Template","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","trim-double-quotes":"Message without quotes","trim-double-quotes-hint":"If selected, request body message payload will be sent without double quotes, i.e. msg = message body","read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Hint: Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Hint: Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Hint: Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required!","end-interval-required":"Interval end is required!","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"entity-details":"Select entity details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","entity-details-list-empty":"No entity details selected!","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-key-name":"Latitude key name","longitude-key-name":"Longitude key name","latitude-key-name-required":"Latitude key name is required.","longitude-key-name-required":"Longitude key name is required.","fetch-perimeter-info-from-message-metadata":"Fetch perimeter information from message metadata","perimeter-key-name":"Perimeter key name","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Please, use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required!","output-value-key":"Output value key","output-value-key-required":"Output value key is required!","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15!","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-cashing":"Use cashing","use-cashing-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required!","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time series","message-body-type":"Message body","message-metadata-type":"Message metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-type-field-input":"Type","argument-type-field-input-required":"Argument type is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Hint: use 0 to convert result to integer","add-to-body-field-input":"Add to message body","add-to-metadata-field-input":"Add to message metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Hint: specify a mathematical expression to evaluate. For example, transform Fahrenheit to Celsius using (x - 32) / 1.8)","retained-message":"Retained","attributes-mapping":"Attributes mapping*","latest-telemetry-mapping":"Latest telemetry mapping*","add-mapped-attribute-to":"Add mapped attributes to:","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to:","add-mapped-fields-to":"Add mapped fields to:","add-selected-details-to":"Add selected details to:","clear-selected-details":"Clear selected details","clear-selected-keys":"Clear selected keys","fetch-credentials-to":"Fetch credentials to:","add-originator-attributes-to":"Add originator attributes to:","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound message metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell Failure","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to:",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output message metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end")!',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch:","mapping-of-customers":"Mapping of customer's:",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to:","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's:","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required"},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping entry","add-entry":"Add entry","unique-key-value-pair-error":"'{{valText}}' must be different from the current '{{keyText}}'"},"mail-body-type":{"plain-text":"Plain Text",html:"HTML",dynamic:"Dynamic"}}},!0)}(e)}}e("RuleNodeCoreConfigModule",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,deps:[{token:_.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),mr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:mr,declarations:[$e],imports:[H,L],exports:[bn,Wn,qn,Bn,ar,sr,$e]}),mr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,imports:[H,L,bn,Wn,qn,Bn,ar,sr]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,decorators:[{type:l,args:[{declarations:[$e],imports:[H,L],exports:[bn,Wn,qn,Bn,ar,sr,$e]}]}],ctorParameters:function(){return[{type:_.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map From dadde5535e5fc6435db31390bded606618ea92fe Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 1 Jun 2023 19:17:23 +0300 Subject: [PATCH 109/207] added dependencies to avoid conflicts --- pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pom.xml b/pom.xml index 34f8f77de1..3eead59f65 100755 --- a/pom.xml +++ b/pom.xml @@ -1335,6 +1335,16 @@ ${netty.version} osx-x86_64 + + com.nimbusds + content-type + 2.2 + + + org.ow2.asm + asm + 8.0.1 + io.netty netty-transport-native-unix-common From c4c7224dd03d7385600b0673046fb11f1c9c9a87 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 2 Jun 2023 11:50:31 +0300 Subject: [PATCH 110/207] removed one level of nesting in transformSuccess method --- .../transform/TbAbstractTransformNode.java | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java index b2a1599e8c..093c76a161 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java @@ -60,25 +60,23 @@ public abstract class TbAbstractTransformNode implements TbNode { } protected void transformSuccess(TbContext ctx, TbMsg msg, List msgs) { - if (msgs != null && !msgs.isEmpty()) { - if (msgs.size() == 1) { - ctx.tellSuccess(msgs.get(0)); - } else { - TbMsgCallbackWrapper wrapper = new MultipleTbMsgsCallbackWrapper(msgs.size(), new TbMsgCallback() { - @Override - public void onSuccess() { - ctx.ack(msg); - } - - @Override - public void onFailure(RuleEngineException e) { - ctx.tellFailure(msg, e); - } - }); - msgs.forEach(newMsg -> ctx.enqueueForTellNext(newMsg, TbRelationTypes.SUCCESS, wrapper::onSuccess, wrapper::onFailure)); - } - } else { + if (msgs == null || msgs.isEmpty()) { ctx.tellFailure(msg, new RuntimeException("Message or messages list are empty!")); + } else if (msgs.size() == 1) { + ctx.tellSuccess(msgs.get(0)); + } else { + TbMsgCallbackWrapper wrapper = new MultipleTbMsgsCallbackWrapper(msgs.size(), new TbMsgCallback() { + @Override + public void onSuccess() { + ctx.ack(msg); + } + + @Override + public void onFailure(RuleEngineException e) { + ctx.tellFailure(msg, e); + } + }); + msgs.forEach(newMsg -> ctx.enqueueForTellNext(newMsg, TbRelationTypes.SUCCESS, wrapper::onSuccess, wrapper::onFailure)); } } From 34c8909adf41aac0b90520ea41eb8d6c1905a370 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 2 Jun 2023 13:05:08 +0300 Subject: [PATCH 111/207] moved servicebus conflicting dependency to exclusions --- pom.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 3eead59f65..f4c4970d7f 100755 --- a/pom.xml +++ b/pom.xml @@ -1335,16 +1335,6 @@ ${netty.version} osx-x86_64 - - com.nimbusds - content-type - 2.2 - - - org.ow2.asm - asm - 8.0.1 - io.netty netty-transport-native-unix-common @@ -1846,6 +1836,16 @@ com.microsoft.azure azure-servicebus ${azure-servicebus.version} + + + com.nimbusds + content-type + + + org.ow2.asm + asm + + org.passay From 3cb7d517a6989ebe41b63b0d422610a72d4a1f21 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 2 Jun 2023 13:15:47 +0300 Subject: [PATCH 112/207] removed unused import in TbAbstractTransformNode --- .../rule/engine/transform/TbAbstractTransformNode.java | 1 - 1 file changed, 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java index 093c76a161..7bf08e8647 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbAbstractTransformNode.java @@ -23,7 +23,6 @@ import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.TbRelationTypes; -import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.queue.RuleEngineException; import org.thingsboard.server.common.msg.queue.TbMsgCallback; From 67656a275706857aa79147b048daf1fc95152629 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 2 Jun 2023 14:50:23 +0300 Subject: [PATCH 113/207] Notifications deduplication --- .../server/actors/ActorSystemContext.java | 2 +- .../DefaultNotificationRuleProcessor.java | 43 +++++++----- .../src/main/resources/thingsboard.yml | 5 ++ .../notification/NotificationRuleApiTest.java | 2 +- .../notification/rule/NotificationRule.java | 10 +++ .../NotificationRuleTriggerConfig.java | 6 ++ .../trigger/NotificationRuleTriggerType.java | 15 +++-- .../settings/TriggerTypeConfig.java | 14 ++-- .../NotificationRuleProcessor.java | 2 +- .../trigger/NewPlatformVersionTrigger.java | 17 +++++ .../trigger/NotificationRuleTrigger.java | 14 ++++ .../RemoteNotificationRuleProcessor.java | 65 ++++++++++++++++++- .../src/main/resources/tb-vc-executor.yml | 9 ++- .../src/main/resources/tb-coap-transport.yml | 7 ++ .../src/main/resources/tb-http-transport.yml | 7 ++ .../src/main/resources/tb-lwm2m-transport.yml | 7 ++ .../src/main/resources/tb-mqtt-transport.yml | 7 ++ .../src/main/resources/tb-snmp-transport.yml | 7 ++ 18 files changed, 201 insertions(+), 38 deletions(-) rename application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineMsgNotificationRuleTriggerProcessor.java => common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/TriggerTypeConfig.java (56%) rename common/{queue/src/main/java/org/thingsboard/server/queue => message/src/main/java/org/thingsboard/server/common/msg}/notification/NotificationRuleProcessor.java (93%) diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index e0190bb388..e04c7052db 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -90,7 +90,7 @@ import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.queue.discovery.DiscoveryService; import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; -import org.thingsboard.server.queue.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.queue.util.DataDecodingEncodingService; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.component.ComponentDiscoveryService; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java index 9c57b3cc77..297ccc4007 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java @@ -66,6 +66,7 @@ import java.util.stream.Collectors; @Service @RequiredArgsConstructor +@ConfigurationProperties(prefix = "notification-system.rules") @Slf4j @SuppressWarnings({"rawtypes", "unchecked"}) public class DefaultNotificationRuleProcessor implements NotificationRuleProcessor { @@ -79,6 +80,8 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess private final NotificationExecutorService notificationExecutor; private final CacheManager cacheManager; private Cache sentNotifications; + @Setter + private Map triggerTypesConfigs; private final Map triggerProcessors = new EnumMap<>(NotificationRuleTriggerType.class); @@ -142,9 +145,6 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess log.debug("[{}] Rate limit for notification requests per rule was exceeded (rule '{}')", rule.getTenantId(), rule.getName()); return; } - if (trigger.getType().isDeduplicate() && alreadySent(rule.getId(), trigger)) { - return; - } NotificationInfo notificationInfo = constructNotificationInfo(trigger, triggerConfig); rule.getRecipientsConfig().getTargetsTable().forEach((delay, targets) -> { @@ -194,23 +194,34 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess return triggerProcessors.get(triggerConfig.getTriggerType()).constructNotificationInfo(trigger); } - private boolean alreadySent(NotificationRuleId ruleId, NotificationRuleTrigger trigger) { - String key = ruleId + "_" + trigger.getOriginatorEntityId(); - SentNotification sent = sentNotifications.get(key, SentNotification.class); - boolean alreadySent; - if (sent != null && sent.getTrigger().equals(trigger)) { - alreadySent = true; - log.debug("Notification for {} trigger was already sent, ignoring", trigger.getType()); - // updating cache anyway so that the value is not removed by ttl - } else { - alreadySent = false; - sent = new SentNotification(trigger); + private boolean alreadySent(NotificationRule rule, NotificationRuleTrigger trigger) { + String deduplicationKey = getDeduplicationKey(trigger, rule); + + boolean alreadySent = false; + Long lastSentTs = sentNotifications.get(deduplicationKey, Long.class); + if (lastSentTs != null) { + long deduplicationDuration = Optional.ofNullable(triggerTypesConfigs) + .map(triggerTypes -> triggerTypes.get(trigger.getType())) + .map(TriggerTypeConfig::getDeduplicationDuration) + .orElseGet(trigger::getDefaultDeduplicationDuration); + long passed = System.currentTimeMillis() - lastSentTs; + log.trace("Deduplicating trigger {} for rule '{}' by key '{}'. Deduplication duration: {} ms, passed: {} ms", + trigger.getType(), rule.getName(), deduplicationKey, deduplicationDuration, passed); + if (deduplicationDuration == 0 || passed <= deduplicationDuration) { + alreadySent = true; + } } - log.trace("[{}] Putting to sentNotifications cache: {}", ruleId, trigger); - sentNotifications.put(key, sent); + if (!alreadySent) { + lastSentTs = System.currentTimeMillis(); + } + sentNotifications.put(deduplicationKey, lastSentTs); return alreadySent; } + public static String getDeduplicationKey(NotificationRuleTrigger trigger, NotificationRule rule) { + return String.join("_", trigger.getDeduplicationKey(), rule.getDeduplicationKey()); + } + @EventListener(ComponentLifecycleMsg.class) public void onNotificationRuleDeleted(ComponentLifecycleMsg componentLifecycleMsg) { if (componentLifecycleMsg.getEvent() != ComponentLifecycleEvent.DELETED || diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 6b05df7feb..f780d42a0d 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -1261,6 +1261,11 @@ vc: notification_system: thread_pool_size: "${TB_NOTIFICATION_SYSTEM_THREAD_POOL_SIZE:10}" + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" management: endpoints: diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java index 455b897fcd..044428e270 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java @@ -444,7 +444,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { } @Test - public void testNotificationsDeduplication() throws Exception { + public void testNotificationsDeduplication_newPlatformVersion() throws Exception { loginSysAdmin(); NewPlatformVersionNotificationRuleTriggerConfig triggerConfig = new NewPlatformVersionNotificationRuleTriggerConfig(); createNotificationRule(triggerConfig, "Test", "Test", createNotificationTarget(tenantAdminUserId).getId()); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java index 5ca8dff863..c88ade5bb1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java @@ -36,6 +36,8 @@ import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; @Data @NoArgsConstructor @@ -84,4 +86,12 @@ public class NotificationRule extends BaseData implements Ha triggerType == recipientsConfig.getTriggerType(); } + @JsonIgnore + public String getDeduplicationKey() { + String targets = recipientsConfig.getTargetsTable().values().stream() + .flatMap(List::stream).sorted().map(Object::toString) + .collect(Collectors.joining(",")); + return String.join(":", targets, triggerConfig.getDeduplicationKey()); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java index 3406a802c7..b0eec28858 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.data.notification.rule.trigger; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; @@ -39,4 +40,9 @@ public interface NotificationRuleTriggerConfig extends Serializable { NotificationRuleTriggerType getTriggerType(); + @JsonIgnore + default String getDeduplicationKey() { + return "#"; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java index e79e7f1195..dff86f4ba1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java @@ -16,10 +16,8 @@ package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Getter; -import lombok.RequiredArgsConstructor; @Getter -@RequiredArgsConstructor public enum NotificationRuleTriggerType { ENTITY_ACTION, @@ -28,15 +26,18 @@ public enum NotificationRuleTriggerType { ALARM_ASSIGNMENT, DEVICE_ACTIVITY, RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, - NEW_PLATFORM_VERSION(false, true), - ENTITIES_LIMIT(false, false), - API_USAGE_LIMIT(false, false); + NEW_PLATFORM_VERSION(false), + ENTITIES_LIMIT(false), + API_USAGE_LIMIT(false); private final boolean tenantLevel; - private final boolean deduplicate; NotificationRuleTriggerType() { - this(true, false); + this(true); + } + + NotificationRuleTriggerType(boolean tenantLevel) { + this.tenantLevel = tenantLevel; } } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineMsgNotificationRuleTriggerProcessor.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/TriggerTypeConfig.java similarity index 56% rename from application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineMsgNotificationRuleTriggerProcessor.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/TriggerTypeConfig.java index ac8f692f02..6991bb1277 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineMsgNotificationRuleTriggerProcessor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/TriggerTypeConfig.java @@ -13,15 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.service.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.settings; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; -import org.thingsboard.server.common.msg.notification.trigger.RuleEngineMsgTrigger; - -import java.util.Set; - -public interface RuleEngineMsgNotificationRuleTriggerProcessor extends NotificationRuleTriggerProcessor { - - Set getSupportedMsgTypes(); +import lombok.Data; +@Data +public class TriggerTypeConfig { + private long deduplicationDuration; } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/notification/NotificationRuleProcessor.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/NotificationRuleProcessor.java similarity index 93% rename from common/queue/src/main/java/org/thingsboard/server/queue/notification/NotificationRuleProcessor.java rename to common/message/src/main/java/org/thingsboard/server/common/msg/notification/NotificationRuleProcessor.java index 1fa9d82863..380773c1b0 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/notification/NotificationRuleProcessor.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/NotificationRuleProcessor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.queue.notification; +package org.thingsboard.server.common.msg.notification; import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTrigger; diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NewPlatformVersionTrigger.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NewPlatformVersionTrigger.java index 0da2f0c57b..2bb88a708b 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NewPlatformVersionTrigger.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NewPlatformVersionTrigger.java @@ -43,4 +43,21 @@ public class NewPlatformVersionTrigger implements NotificationRuleTrigger { return TenantId.SYS_TENANT_ID; } + + @Override + public boolean deduplicate() { + return true; + } + + @Override + public String getDeduplicationKey() { + return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), + updateInfo.getCurrentVersion(), updateInfo.getLatestVersion()); + } + + @Override + public long getDefaultDeduplicationDuration() { + return 0; + } + } diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NotificationRuleTrigger.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NotificationRuleTrigger.java index b511062549..0cfc87a4df 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NotificationRuleTrigger.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NotificationRuleTrigger.java @@ -29,4 +29,18 @@ public interface NotificationRuleTrigger extends Serializable { EntityId getOriginatorEntityId(); + + default boolean deduplicate() { + return false; + } + + default String getDeduplicationKey() { + EntityId originatorEntityId = getOriginatorEntityId(); + return String.join(":", getType().toString(), originatorEntityId.getEntityType().toString(), originatorEntityId.getId().toString()); + } + + default long getDefaultDeduplicationDuration() { + return 0; + } + } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java b/common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java index 3c3988389f..617fdbb50e 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java @@ -19,7 +19,12 @@ import com.google.protobuf.ByteString; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Service; +import org.springframework.util.ConcurrentReferenceHashMap; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.settings.TriggerTypeConfig; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; @@ -30,10 +35,17 @@ import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.util.DataDecodingEncodingService; +import java.util.EnumMap; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.springframework.util.ConcurrentReferenceHashMap.ReferenceType.SOFT; @Service @ConditionalOnMissingBean(value = NotificationRuleProcessor.class, ignored = RemoteNotificationRuleProcessor.class) +@ConfigurationProperties(prefix = "notification-system.rules") @RequiredArgsConstructor @Slf4j public class RemoteNotificationRuleProcessor implements NotificationRuleProcessor { @@ -43,10 +55,16 @@ public class RemoteNotificationRuleProcessor implements NotificationRuleProcesso private final PartitionService partitionService; private final DataDecodingEncodingService encodingService; + private Map triggerTypesConfigs; + private final ConcurrentMap submittedTriggers = new ConcurrentReferenceHashMap<>(16, SOFT); + @Override public void process(NotificationRuleTrigger trigger) { + if (trigger.deduplicate() && alreadySubmitted(trigger)) { + return; + } try { - log.trace("Submitting notification rule trigger: {}", trigger); + log.debug("Submitting notification rule trigger: {}", trigger); TransportProtos.NotificationRuleProcessorMsg.Builder msg = TransportProtos.NotificationRuleProcessorMsg.newBuilder() .setTrigger(ByteString.copyFrom(encodingService.encode(trigger))); @@ -57,9 +75,52 @@ public class RemoteNotificationRuleProcessor implements NotificationRuleProcesso .setNotificationRuleProcessorMsg(msg) .build()), null); }); - } catch (Exception e) { + } catch (Throwable e) { log.error("Failed to submit notification rule trigger: {}", trigger, e); } } + private boolean alreadySubmitted(NotificationRuleTrigger trigger) { + String deduplicationKey = trigger.getDeduplicationKey(); + + AtomicBoolean alreadySubmitted = new AtomicBoolean(false); + submittedTriggers.compute(deduplicationKey, (key, lastSubmittedTs) -> { + long currentTs = System.currentTimeMillis(); + if (lastSubmittedTs == null) { + return currentTs; + } else { + long deduplicationDuration = getDeduplicationDuration(trigger); + long passed = currentTs - lastSubmittedTs; + if (deduplicationDuration == 0 || passed <= deduplicationDuration) { + log.trace("Notification rule trigger {} was already submitted {} ms ago, deduplication duration is {} ms. Key: '{}'", + trigger.getType(), passed, deduplicationDuration, deduplicationKey); + alreadySubmitted.set(true); + return lastSubmittedTs; + } else { + return currentTs; + } + } + }); + return alreadySubmitted.get(); + } + + private long getDeduplicationDuration(NotificationRuleTrigger trigger) { + if (triggerTypesConfigs == null) { + triggerTypesConfigs = new EnumMap<>(NotificationRuleTriggerType.class); + } + TriggerTypeConfig triggerTypeConfig = triggerTypesConfigs.computeIfAbsent(trigger.getType(), triggerType -> { + TriggerTypeConfig config = new TriggerTypeConfig(); + config.setDeduplicationDuration(trigger.getDefaultDeduplicationDuration()); + return config; + }); + return triggerTypeConfig.getDeduplicationDuration(); + } + + // set from ConfigurationProperties + public void setTriggerTypesConfigs(Map triggerTypesConfigs) { + if (triggerTypesConfigs != null) { + this.triggerTypesConfigs = new EnumMap<>(triggerTypesConfigs); + } + } + } diff --git a/msa/vc-executor/src/main/resources/tb-vc-executor.yml b/msa/vc-executor/src/main/resources/tb-vc-executor.yml index ca495c678f..75f9e09d3c 100644 --- a/msa/vc-executor/src/main/resources/tb-vc-executor.yml +++ b/msa/vc-executor/src/main/resources/tb-vc-executor.yml @@ -202,4 +202,11 @@ management: service: type: "${TB_SERVICE_TYPE:tb-vc-executor}" # Unique id for this service (autogenerated if empty) - id: "${TB_SERVICE_ID:}" \ No newline at end of file + id: "${TB_SERVICE_ID:}" + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 7ea553fe5c..8fe079859a 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -302,3 +302,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index 346ec48eae..f05db08643 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -287,3 +287,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 4e8167d89d..745a7d126a 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -369,3 +369,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index 1e0b1ebcd4..3795c533a7 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -317,3 +317,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index 9f086bcbc5..11dcc96010 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -267,3 +267,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" From f5cd8a9a52989c188e6bad899d7ed9fbb285c41d Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 2 Jun 2023 14:57:00 +0300 Subject: [PATCH 114/207] Notification system - less async operations --- .../DefaultTbApiUsageStateService.java | 2 +- .../DefaultNotificationCenter.java | 103 +++++++----------- .../channels/EmailNotificationChannel.java | 20 ++-- .../channels/NotificationChannel.java | 3 +- .../channels/SlackNotificationChannel.java | 10 +- .../channels/SmsNotificationChannel.java | 13 +-- .../DefaultNotificationRuleProcessor.java | 62 +++++------ .../cache/DefaultNotificationRulesCache.java | 15 +-- .../queue/DefaultTbCoreConsumerService.java | 2 +- .../DefaultAlarmSubscriptionService.java | 2 +- .../service/update/DefaultUpdateService.java | 2 +- .../src/main/resources/thingsboard.yml | 6 +- .../NotificationRequestStats.java | 3 + .../common/data/util/CollectionsUtil.java | 16 ++- .../src/main/resources/tb-vc-executor.yml | 7 -- .../src/main/resources/tb-coap-transport.yml | 7 -- .../src/main/resources/tb-http-transport.yml | 7 -- .../src/main/resources/tb-lwm2m-transport.yml | 7 -- .../src/main/resources/tb-mqtt-transport.yml | 7 -- .../src/main/resources/tb-snmp-transport.yml | 7 -- 20 files changed, 100 insertions(+), 201 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java index 9e17641c69..7e2719598c 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java @@ -61,7 +61,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceM import org.thingsboard.server.gen.transport.TransportProtos.UsageStatsKVProto; import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.discovery.PartitionService; -import org.thingsboard.server.queue.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.service.apiusage.BaseApiUsageState.StatsCalculationResult; import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.mail.MailExecutorService; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java index 0cb9dc780b..7215776170 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java @@ -15,13 +15,10 @@ */ package org.thingsboard.server.service.notification; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.rule.engine.api.NotificationCenter; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; @@ -59,14 +56,12 @@ import org.thingsboard.server.dao.notification.NotificationService; import org.thingsboard.server.dao.notification.NotificationSettingsService; import org.thingsboard.server.dao.notification.NotificationTargetService; import org.thingsboard.server.dao.notification.NotificationTemplateService; -import org.thingsboard.server.dao.user.UserService; +import org.thingsboard.server.dao.util.limits.LimitedApi; +import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.discovery.NotificationsTopicService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; -import org.thingsboard.server.dao.util.limits.LimitedApi; -import org.thingsboard.server.dao.util.limits.RateLimitService; -import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.NotificationExecutorService; import org.thingsboard.server.service.notification.channels.NotificationChannel; import org.thingsboard.server.service.subscription.TbSubscriptionUtils; @@ -74,7 +69,6 @@ import org.thingsboard.server.service.telemetry.AbstractSubscriptionService; import org.thingsboard.server.service.ws.notification.sub.NotificationRequestUpdate; import org.thingsboard.server.service.ws.notification.sub.NotificationUpdate; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -87,7 +81,7 @@ import java.util.stream.Collectors; @Service @Slf4j @RequiredArgsConstructor -@SuppressWarnings({"UnstableApiUsage", "rawtypes"}) +@SuppressWarnings({"rawtypes"}) public class DefaultNotificationCenter extends AbstractSubscriptionService implements NotificationCenter, NotificationChannel { private final NotificationTargetService notificationTargetService; @@ -95,9 +89,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple private final NotificationService notificationService; private final NotificationTemplateService notificationTemplateService; private final NotificationSettingsService notificationSettingsService; - private final UserService userService; private final NotificationExecutorService notificationExecutor; - private final DbCallbackExecutorService dbCallbackExecutorService; private final NotificationsTopicService notificationsTopicService; private final TbQueueProducerProvider producerProvider; private final RateLimitService rateLimitService; @@ -172,37 +164,32 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple .build(); notificationExecutor.submit(() -> { - List> results = new ArrayList<>(); - for (NotificationTarget target : targets) { - List> result = processForTarget(target, ctx); - results.addAll(result); + processForTarget(target, ctx); + } + + NotificationRequestId requestId = ctx.getRequest().getId(); + log.debug("[{}] Notification request processing is finished", requestId); + NotificationRequestStats stats = ctx.getStats(); + try { + notificationRequestService.updateNotificationRequest(tenantId, requestId, NotificationRequestStatus.SENT, stats); + } catch (Exception e) { + log.error("[{}] Failed to update stats for notification request", requestId, e); } - Futures.whenAllComplete(results).run(() -> { - NotificationRequestId requestId = ctx.getRequest().getId(); - log.debug("[{}] Notification request processing is finished", requestId); - NotificationRequestStats stats = ctx.getStats(); + if (callback != null) { try { - notificationRequestService.updateNotificationRequest(tenantId, requestId, NotificationRequestStatus.SENT, stats); + callback.accept(stats); } catch (Exception e) { - log.error("[{}] Failed to update stats for notification request", requestId, e); - } - - if (callback != null) { - try { - callback.accept(stats); - } catch (Exception e) { - log.error("Failed to process callback for notification request {}", requestId, e); - } + log.error("Failed to process callback for notification request {}", requestId, e); } - }, dbCallbackExecutorService); + } }); return request; } - private List> processForTarget(NotificationTarget target, NotificationProcessingContext ctx) { + private void processForTarget(NotificationTarget target, NotificationProcessingContext ctx) { Iterable recipients; switch (target.getConfiguration().getType()) { case PLATFORM_USERS: { @@ -231,43 +218,35 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple Set deliveryMethods = new HashSet<>(ctx.getDeliveryMethods()); deliveryMethods.removeIf(deliveryMethod -> !target.getConfiguration().getType().getSupportedDeliveryMethods().contains(deliveryMethod)); log.debug("[{}] Processing notification request for {} target ({}) for delivery methods {}", ctx.getRequest().getId(), target.getConfiguration().getType(), target.getId(), deliveryMethods); + if (deliveryMethods.isEmpty()) { + return; + } - List> results = new ArrayList<>(); - if (!deliveryMethods.isEmpty()) { - for (NotificationRecipient recipient : recipients) { - for (NotificationDeliveryMethod deliveryMethod : deliveryMethods) { - ListenableFuture resultFuture = processForRecipient(deliveryMethod, recipient, ctx); - DonAsynchron.withCallback(resultFuture, result -> { - ctx.getStats().reportSent(deliveryMethod, recipient); - }, error -> { - ctx.getStats().reportError(deliveryMethod, error, recipient); - }); - results.add(resultFuture); + for (NotificationRecipient recipient : recipients) { + for (NotificationDeliveryMethod deliveryMethod : deliveryMethods) { + try { + processForRecipient(deliveryMethod, recipient, ctx); + ctx.getStats().reportSent(deliveryMethod, recipient); + } catch (Exception error) { + ctx.getStats().reportError(deliveryMethod, error, recipient); } } } - return results; } - private ListenableFuture processForRecipient(NotificationDeliveryMethod deliveryMethod, NotificationRecipient recipient, NotificationProcessingContext ctx) { + private void processForRecipient(NotificationDeliveryMethod deliveryMethod, NotificationRecipient recipient, NotificationProcessingContext ctx) throws Exception { if (ctx.getStats().contains(deliveryMethod, recipient.getId())) { - return Futures.immediateFailedFuture(new AlreadySentException()); + throw new AlreadySentException(); } - - DeliveryMethodNotificationTemplate processedTemplate; - try { - processedTemplate = ctx.getProcessedTemplate(deliveryMethod, recipient); - } catch (Exception e) { - return Futures.immediateFailedFuture(e); - } - NotificationChannel notificationChannel = channels.get(deliveryMethod); + DeliveryMethodNotificationTemplate processedTemplate = ctx.getProcessedTemplate(deliveryMethod, recipient); + log.trace("[{}] Sending {} notification for recipient {}", ctx.getRequest().getId(), deliveryMethod, recipient); - return notificationChannel.sendNotification(recipient, processedTemplate, ctx); + notificationChannel.sendNotification(recipient, processedTemplate, ctx); } @Override - public ListenableFuture sendNotification(User recipient, WebDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { + public void sendNotification(User recipient, WebDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) throws Exception { NotificationRequest request = ctx.getRequest(); Notification notification = Notification.builder() .requestId(request.getId()) @@ -283,14 +262,14 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple notification = notificationService.saveNotification(recipient.getTenantId(), notification); } catch (Exception e) { log.error("Failed to create notification for recipient {}", recipient.getId(), e); - return Futures.immediateFailedFuture(e); + throw e; } NotificationUpdate update = NotificationUpdate.builder() .created(true) .notification(notification) .build(); - return onNotificationUpdate(recipient.getTenantId(), recipient.getId(), update); + onNotificationUpdate(recipient.getTenantId(), recipient.getId(), update); } @Override @@ -384,13 +363,11 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple clusterService.pushMsgToCore(tenantId, notificationRequestId, toCoreMsg, null); } - private ListenableFuture onNotificationUpdate(TenantId tenantId, UserId recipientId, NotificationUpdate update) { + private void onNotificationUpdate(TenantId tenantId, UserId recipientId, NotificationUpdate update) { log.trace("Submitting notification update for recipient {}: {}", recipientId, update); - return Futures.submit(() -> { - forwardToSubscriptionManagerService(tenantId, recipientId, subscriptionManagerService -> { - subscriptionManagerService.onNotificationUpdate(tenantId, recipientId, update, TbCallback.EMPTY); - }, () -> TbSubscriptionUtils.notificationUpdateToProto(tenantId, recipientId, update)); - }, wsCallBackExecutor); + forwardToSubscriptionManagerService(tenantId, recipientId, subscriptionManagerService -> { + subscriptionManagerService.onNotificationUpdate(tenantId, recipientId, update, TbCallback.EMPTY); + }, () -> TbSubscriptionUtils.notificationUpdateToProto(tenantId, recipientId, update)); } private void onNotificationRequestUpdate(TenantId tenantId, NotificationRequestUpdate update) { diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/EmailNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/EmailNotificationChannel.java index 8b3c9551c2..8e9e8525e3 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/EmailNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/EmailNotificationChannel.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.notification.channels; -import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.thingsboard.rule.engine.api.MailService; @@ -24,7 +23,6 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate; -import org.thingsboard.server.service.mail.MailExecutorService; import org.thingsboard.server.service.notification.NotificationProcessingContext; @Component @@ -32,19 +30,15 @@ import org.thingsboard.server.service.notification.NotificationProcessingContext public class EmailNotificationChannel implements NotificationChannel { private final MailService mailService; - private final MailExecutorService executor; @Override - public ListenableFuture sendNotification(User recipient, EmailDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { - return executor.submit(() -> { - mailService.send(recipient.getTenantId(), null, TbEmail.builder() - .to(recipient.getEmail()) - .subject(processedTemplate.getSubject()) - .body(processedTemplate.getBody()) - .html(true) - .build()); - return null; - }); + public void sendNotification(User recipient, EmailDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) throws Exception { + mailService.send(recipient.getTenantId(), null, TbEmail.builder() + .to(recipient.getEmail()) + .subject(processedTemplate.getSubject()) + .body(processedTemplate.getBody()) + .html(true) + .build()); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/NotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/NotificationChannel.java index 02fe6264d2..0275644765 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/NotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/NotificationChannel.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.notification.channels; -import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.targets.NotificationRecipient; @@ -24,7 +23,7 @@ import org.thingsboard.server.service.notification.NotificationProcessingContext public interface NotificationChannel { - ListenableFuture sendNotification(R recipient, T processedTemplate, NotificationProcessingContext ctx); + void sendNotification(R recipient, T processedTemplate, NotificationProcessingContext ctx) throws Exception; void check(TenantId tenantId) throws Exception; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/SlackNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/SlackNotificationChannel.java index 46afbd7270..25c6b9dcab 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/SlackNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/SlackNotificationChannel.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.notification.channels; -import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.thingsboard.rule.engine.api.slack.SlackService; @@ -26,7 +25,6 @@ import org.thingsboard.server.common.data.notification.settings.SlackNotificatio import org.thingsboard.server.common.data.notification.targets.slack.SlackConversation; import org.thingsboard.server.common.data.notification.template.SlackDeliveryMethodNotificationTemplate; import org.thingsboard.server.dao.notification.NotificationSettingsService; -import org.thingsboard.server.service.executors.ExternalCallExecutorService; import org.thingsboard.server.service.notification.NotificationProcessingContext; @Component @@ -35,15 +33,11 @@ public class SlackNotificationChannel implements NotificationChannel sendNotification(SlackConversation conversation, SlackDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { + public void sendNotification(SlackConversation conversation, SlackDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) throws Exception { SlackNotificationDeliveryMethodConfig config = ctx.getDeliveryMethodConfig(NotificationDeliveryMethod.SLACK); - return executor.submit(() -> { - slackService.sendMessage(ctx.getTenantId(), config.getBotToken(), conversation.getId(), processedTemplate.getBody()); - return null; - }); + slackService.sendMessage(ctx.getTenantId(), config.getBotToken(), conversation.getId(), processedTemplate.getBody()); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/SmsNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/SmsNotificationChannel.java index 3c44dabd4b..44b61d3bb3 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/SmsNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/SmsNotificationChannel.java @@ -15,8 +15,6 @@ */ package org.thingsboard.server.service.notification.channels; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; @@ -26,26 +24,21 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.template.SmsDeliveryMethodNotificationTemplate; import org.thingsboard.server.service.notification.NotificationProcessingContext; -import org.thingsboard.server.service.sms.SmsExecutorService; @Component @RequiredArgsConstructor public class SmsNotificationChannel implements NotificationChannel { private final SmsService smsService; - private final SmsExecutorService executor; @Override - public ListenableFuture sendNotification(User recipient, SmsDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { + public void sendNotification(User recipient, SmsDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) throws Exception { String phone = recipient.getPhone(); if (StringUtils.isBlank(phone)) { - return Futures.immediateFailedFuture(new RuntimeException("User does not have phone number")); + throw new RuntimeException("User does not have phone number"); } - return executor.submit(() -> { - smsService.sendSms(recipient.getTenantId(), recipient.getCustomerId(), new String[]{phone}, processedTemplate.getBody()); - return null; - }); + smsService.sendSms(recipient.getTenantId(), recipient.getCustomerId(), new String[]{phone}, processedTemplate.getBody()); } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java index 297ccc4007..71a59026a2 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java @@ -15,10 +15,11 @@ */ package org.thingsboard.server.service.notification.rule; -import lombok.Data; import lombok.RequiredArgsConstructor; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Lazy; @@ -38,29 +39,27 @@ import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.settings.TriggerTypeConfig; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTrigger; -import org.thingsboard.server.common.msg.notification.trigger.RuleEngineMsgTrigger; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.queue.discovery.PartitionService; -import org.thingsboard.server.queue.notification.NotificationRuleProcessor; import org.thingsboard.server.service.executors.NotificationExecutorService; import org.thingsboard.server.service.notification.rule.cache.NotificationRulesCache; import org.thingsboard.server.service.notification.rule.trigger.NotificationRuleTriggerProcessor; -import org.thingsboard.server.service.notification.rule.trigger.RuleEngineMsgNotificationRuleTriggerProcessor; import javax.annotation.PostConstruct; -import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -96,20 +95,27 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess @Override public void process(NotificationRuleTrigger trigger) { NotificationRuleTriggerType triggerType = trigger.getType(); - if (triggerType == null) return; TenantId tenantId = triggerType.isTenantLevel() ? trigger.getTenantId() : TenantId.SYS_TENANT_ID; try { - List rules = notificationRulesCache.getEnabled(tenantId, triggerType); - for (NotificationRule rule : rules) { - notificationExecutor.submit(() -> { + List enabledRules = notificationRulesCache.getEnabled(tenantId, triggerType); + if (enabledRules.isEmpty()) { + return; + } + if (trigger.deduplicate()) { + enabledRules = new ArrayList<>(enabledRules); + enabledRules.removeIf(rule -> alreadySent(rule, trigger)); + } + final List rules = enabledRules; + notificationExecutor.submit(() -> { + for (NotificationRule rule : rules) { try { processNotificationRule(rule, trigger); } catch (Throwable e) { log.error("Failed to process notification rule {} for trigger type {} with trigger object {}", rule.getId(), rule.getTriggerType(), trigger, e); } - }); - } + } + }); } catch (Throwable e) { log.error("Failed to process notification rules for trigger: {}", trigger, e); } @@ -172,14 +178,13 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess .ruleId(rule.getId()) .originatorEntityId(originatorEntityId) .build(); - notificationExecutor.submit(() -> { - try { - log.debug("Submitting notification request for rule '{}' with delay of {} sec to targets {}", rule.getName(), delayInSec, targets); - notificationCenter.processNotificationRequest(rule.getTenantId(), notificationRequest, null); - } catch (Exception e) { - log.error("Failed to process notification request for tenant {} for rule {}", rule.getTenantId(), rule.getId(), e); - } - }); + + try { + log.debug("Submitting notification request for rule '{}' with delay of {} sec to targets {}", rule.getName(), delayInSec, targets); + notificationCenter.processNotificationRequest(rule.getTenantId(), notificationRequest, null); + } catch (Exception e) { + log.error("Failed to process notification request for tenant {} for rule {}", rule.getTenantId(), rule.getId(), e); + } } private boolean matchesFilter(NotificationRuleTrigger trigger, NotificationRuleTriggerConfig triggerConfig) { @@ -243,24 +248,9 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess @Autowired public void setTriggerProcessors(Collection processors) { - Map ruleEngineMsgTypeToTriggerType = new HashMap<>(); processors.forEach(processor -> { triggerProcessors.put(processor.getTriggerType(), processor); - if (processor instanceof RuleEngineMsgNotificationRuleTriggerProcessor) { - Set supportedMsgTypes = ((RuleEngineMsgNotificationRuleTriggerProcessor) processor).getSupportedMsgTypes(); - supportedMsgTypes.forEach(supportedMsgType -> { - ruleEngineMsgTypeToTriggerType.put(supportedMsgType, processor.getTriggerType()); - }); - } }); - RuleEngineMsgTrigger.msgTypeToTriggerType = ruleEngineMsgTypeToTriggerType; - } - - @Data - private static class SentNotification implements Serializable { - private static final long serialVersionUID = 38973480405095422L; - - private final NotificationRuleTrigger trigger; } } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java index a02b7bf1e4..a43ed59efa 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java @@ -17,7 +17,6 @@ package org.thingsboard.server.service.notification.rule.cache; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; -import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -50,7 +49,7 @@ public class DefaultNotificationRulesCache implements NotificationRulesCache { private int cacheMaxSize; @Value("${cache.notificationRules.timeToLiveInMinutes:30}") private int cacheValueTtl; - private Cache> cache; + private Cache> cache; private final ReadWriteLock lock = new ReentrantReadWriteLock(); @@ -96,21 +95,15 @@ public class DefaultNotificationRulesCache implements NotificationRulesCache { } } - private void evict(TenantId tenantId) { + public void evict(TenantId tenantId) { cache.invalidateAll(Arrays.stream(NotificationRuleTriggerType.values()) .map(triggerType -> key(tenantId, triggerType)) .collect(Collectors.toList())); log.trace("Evicted all notification rules for tenant {} from cache", tenantId); } - private static CacheKey key(TenantId tenantId, NotificationRuleTriggerType triggerType) { - return new CacheKey(tenantId, triggerType); - } - - @Data - private static class CacheKey { - private final TenantId tenantId; - private final NotificationRuleTriggerType triggerType; + private static String key(TenantId tenantId, NotificationRuleTriggerType triggerType) { + return tenantId + "_" + triggerType; } } diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java index 2bd0043046..182fce1c48 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java @@ -63,7 +63,7 @@ import org.thingsboard.server.queue.TbQueueConsumer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; -import org.thingsboard.server.queue.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.queue.provider.TbCoreQueueFactory; import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.DataDecodingEncodingService; diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java index fec9d10a18..e7f2a5a66f 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java @@ -52,7 +52,7 @@ import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.dao.alarm.AlarmOperationResult; import org.thingsboard.server.dao.alarm.AlarmService; -import org.thingsboard.server.queue.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService; import org.thingsboard.server.service.subscription.TbSubscriptionUtils; diff --git a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java index ef066a73f6..587d86af32 100644 --- a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java @@ -29,7 +29,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.UpdateMessage; import org.thingsboard.server.common.msg.notification.trigger.NewPlatformVersionTrigger; -import org.thingsboard.server.queue.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbCoreComponent; diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index f780d42a0d..392587c869 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -1263,9 +1263,9 @@ notification_system: thread_pool_size: "${TB_NOTIFICATION_SYSTEM_THREAD_POOL_SIZE:10}" rules: trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" + NEW_PLATFORM_VERSION: + # In milliseconds, infinitely by default + deduplication_duration: "${NEW_PLATFORM_VERSION_NOTIFICATION_RULE_DEDUPLICATION_DURATION:0}" management: endpoints: diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestStats.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestStats.java index 31e05a2cb3..619e1ad38f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestStats.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestStats.java @@ -62,6 +62,9 @@ public class NotificationRequestStats { return; } String errorMessage = error.getMessage(); + if (errorMessage == null) { + errorMessage = error.getClass().getSimpleName(); + } errors.computeIfAbsent(deliveryMethod, k -> new ConcurrentHashMap<>()).put(recipient.getTitle(), errorMessage); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java index d8d17613de..a0736ca50e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/CollectionsUtil.java @@ -16,7 +16,6 @@ package org.thingsboard.server.common.data.util; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -51,20 +50,19 @@ public class CollectionsUtil { } @SuppressWarnings("unchecked") - public static Map mapOf(Object... kvs) { - Map map = new HashMap<>(); + public static Map mapOf(T... kvs) { + if (kvs.length % 2 != 0) { + throw new IllegalArgumentException("Invalid number of parameters"); + } + Map map = new HashMap<>(); for (int i = 0; i < kvs.length; i += 2) { - K key = (K) kvs[i]; - V value = (V) kvs[i + 1]; + T key = kvs[i]; + T value = kvs[i + 1]; map.put(key, value); } return map; } - public static Map unmodifiableMapOf(Object... kvs) { - return Collections.unmodifiableMap(mapOf(kvs)); - } - public static boolean emptyOrContains(Collection collection, V element) { return isEmpty(collection) || collection.contains(element); } diff --git a/msa/vc-executor/src/main/resources/tb-vc-executor.yml b/msa/vc-executor/src/main/resources/tb-vc-executor.yml index 75f9e09d3c..9d5ad35388 100644 --- a/msa/vc-executor/src/main/resources/tb-vc-executor.yml +++ b/msa/vc-executor/src/main/resources/tb-vc-executor.yml @@ -203,10 +203,3 @@ service: type: "${TB_SERVICE_TYPE:tb-vc-executor}" # Unique id for this service (autogenerated if empty) id: "${TB_SERVICE_ID:}" - -notification_system: - rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 8fe079859a..7ea553fe5c 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -302,10 +302,3 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' - -notification_system: - rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index f05db08643..346ec48eae 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -287,10 +287,3 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' - -notification_system: - rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 745a7d126a..4e8167d89d 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -369,10 +369,3 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' - -notification_system: - rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index 3795c533a7..1e0b1ebcd4 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -317,10 +317,3 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' - -notification_system: - rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index 11dcc96010..9f086bcbc5 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -267,10 +267,3 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' - -notification_system: - rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" From 64571eeff22f7f1e8352fb70231d6f58863337d5 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 2 Jun 2023 14:58:12 +0300 Subject: [PATCH 115/207] Don't use Rule Engine message as notification rule trigger --- .../server/actors/tenant/TenantActor.java | 5 -- .../controller/AlarmCommentController.java | 2 +- .../service/action/EntityActionService.java | 67 ++++++++++++++---- .../AlarmAssignmentTriggerProcessor.java | 39 ++++------- .../trigger/AlarmCommentTriggerProcessor.java | 70 +++++++++---------- .../DeviceActivityTriggerProcessor.java | 38 ++++------ .../state/DefaultDeviceStateService.java | 25 +++++-- .../state/DefaultDeviceStateServiceTest.java | 6 +- ...igger.java => AlarmAssignmentTrigger.java} | 22 +++--- .../trigger/AlarmCommentTrigger.java | 48 +++++++++++++ .../trigger/ApiUsageLimitTrigger.java | 5 -- .../trigger/DeviceActivityTrigger.java | 49 +++++++++++++ 12 files changed, 242 insertions(+), 134 deletions(-) rename common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/{RuleEngineMsgTrigger.java => AlarmAssignmentTrigger.java} (71%) create mode 100644 common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmCommentTrigger.java create mode 100644 common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/DeviceActivityTrigger.java diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index 84b7757846..11a5895fef 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -49,7 +49,6 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; import org.thingsboard.server.common.msg.edge.EdgeSessionMsg; -import org.thingsboard.server.common.msg.notification.trigger.RuleEngineMsgTrigger; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; @@ -211,10 +210,6 @@ public class TenantActor extends RuleChainManagerActor { log.trace("[{}] Ack message because Rule Engine is disabled", tenantId); tbMsg.getCallback().onSuccess(); } - systemContext.getNotificationRuleProcessor().process(RuleEngineMsgTrigger.builder() - .tenantId(tenantId) - .msg(tbMsg) - .build()); } private void onRuleChainMsg(RuleChainAwareMsg msg) { diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java index 92b2cb923f..12195e83bc 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java @@ -77,7 +77,7 @@ public class AlarmCommentController extends BaseController { @PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = "A JSON value representing the comment.") @RequestBody AlarmComment alarmComment) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); - Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); + Alarm alarm = checkAlarmInfoId(alarmId, Operation.WRITE); alarmComment.setAlarmId(alarmId); return tbAlarmCommentService.saveAlarmComment(alarm, alarmComment, getCurrentUser()); } diff --git a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java index 623b95b40e..99b508a12d 100644 --- a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java +++ b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java @@ -28,7 +28,9 @@ import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmComment; +import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.CustomerId; @@ -40,10 +42,12 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.trigger.AlarmAssignmentTrigger; +import org.thingsboard.server.common.msg.notification.trigger.AlarmCommentTrigger; import org.thingsboard.server.common.msg.notification.trigger.EntitiesLimitTrigger; import org.thingsboard.server.common.msg.notification.trigger.EntityActionTrigger; import org.thingsboard.server.dao.audit.AuditLogService; -import org.thingsboard.server.queue.notification.NotificationRuleProcessor; import java.util.List; import java.util.Map; @@ -241,19 +245,7 @@ public class EntityActionService { } } if (tenantId != null && !tenantId.isSysTenantId()) { - if (actionType == ActionType.ADDED) { - notificationRuleProcessor.process(EntitiesLimitTrigger.builder() - .tenantId(tenantId) - .entityType(entityId.getEntityType()) - .build()); - } - notificationRuleProcessor.process(EntityActionTrigger.builder() - .tenantId(tenantId) - .entityId(entityId) - .entity(entity) - .actionType(actionType) - .user(user) - .build()); + processNotificationRules(tenantId, entityId, entity, actionType, user, additionalInfo); } TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null); @@ -263,6 +255,53 @@ public class EntityActionService { } } + private void processNotificationRules(TenantId tenantId, EntityId entityId, HasName entity, ActionType actionType, User user, Object... additionalInfo) { + switch (actionType) { + case ADDED: + notificationRuleProcessor.process(EntitiesLimitTrigger.builder() + .tenantId(tenantId) + .entityType(entityId.getEntityType()) + .build()); + case UPDATED: + case DELETED: + notificationRuleProcessor.process(EntityActionTrigger.builder() + .tenantId(tenantId) + .entityId(entityId) + .entity(entity) + .actionType(actionType) + .user(user) + .build()); + break; + case ALARM_ASSIGNED: + case ALARM_UNASSIGNED: + if (!(entity instanceof AlarmInfo)) { // should not normally happen + log.warn("Invalid alarm assignment event: entity is not instance of AlarmInfo"); + break; + } + notificationRuleProcessor.process(AlarmAssignmentTrigger.builder() + .tenantId(tenantId) + .alarmInfo((AlarmInfo) entity) + .actionType(actionType) + .user(user) + .build()); + break; + case ADDED_COMMENT: + case UPDATED_COMMENT: + if (!(entity instanceof Alarm)) { // should not normally happen + log.warn("Invalid alarm comment event: entity is not instance of Alarm"); + break; + } + notificationRuleProcessor.process(AlarmCommentTrigger.builder() + .tenantId(tenantId) + .comment(extractParameter(AlarmComment.class, 0, additionalInfo)) + .alarm((Alarm) entity) + .actionType(actionType) + .user(user) + .build()); + break; + } + } + public void logEntityAction(User user, I entityId, E entity, CustomerId customerId, ActionType actionType, Exception e, Object... additionalInfo) { if (customerId == null || customerId.isNullUid()) { diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java index ed72f6be58..eca258aecc 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java @@ -16,52 +16,48 @@ package org.thingsboard.server.service.notification.rule.trigger; import org.springframework.stereotype.Service; -import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.data.DataConstants; -import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmAssignee; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.notification.info.AlarmAssignmentNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig.Action; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.RuleEngineMsgTrigger; - -import java.util.Set; +import org.thingsboard.server.common.msg.notification.trigger.AlarmAssignmentTrigger; import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; @Service -public class AlarmAssignmentTriggerProcessor implements RuleEngineMsgNotificationRuleTriggerProcessor { +public class AlarmAssignmentTriggerProcessor implements NotificationRuleTriggerProcessor { @Override - public boolean matchesFilter(RuleEngineMsgTrigger trigger, AlarmAssignmentNotificationRuleTriggerConfig triggerConfig) { - Action action = trigger.getMsg().getType().equals(DataConstants.ALARM_ASSIGNED) ? Action.ASSIGNED : Action.UNASSIGNED; + public boolean matchesFilter(AlarmAssignmentTrigger trigger, AlarmAssignmentNotificationRuleTriggerConfig triggerConfig) { + Action action = trigger.getActionType() == ActionType.ALARM_ASSIGNED ? Action.ASSIGNED : Action.UNASSIGNED; if (!triggerConfig.getNotifyOn().contains(action)) { return false; } - Alarm alarm = JacksonUtil.fromString(trigger.getMsg().getData(), Alarm.class); - return emptyOrContains(triggerConfig.getAlarmTypes(), alarm.getType()) && - emptyOrContains(triggerConfig.getAlarmSeverities(), alarm.getSeverity()) && - (isEmpty(triggerConfig.getAlarmStatuses()) || AlarmStatusFilter.from(triggerConfig.getAlarmStatuses()).matches(alarm)); + AlarmInfo alarmInfo = trigger.getAlarmInfo(); + return emptyOrContains(triggerConfig.getAlarmTypes(), alarmInfo.getType()) && + emptyOrContains(triggerConfig.getAlarmSeverities(), alarmInfo.getSeverity()) && + (isEmpty(triggerConfig.getAlarmStatuses()) || AlarmStatusFilter.from(triggerConfig.getAlarmStatuses()).matches(alarmInfo)); } @Override - public RuleOriginatedNotificationInfo constructNotificationInfo(RuleEngineMsgTrigger trigger) { - AlarmInfo alarmInfo = JacksonUtil.fromString(trigger.getMsg().getData(), AlarmInfo.class); + public RuleOriginatedNotificationInfo constructNotificationInfo(AlarmAssignmentTrigger trigger) { + AlarmInfo alarmInfo = trigger.getAlarmInfo(); AlarmAssignee assignee = alarmInfo.getAssignee(); return AlarmAssignmentNotificationInfo.builder() - .action(trigger.getMsg().getType().equals(DataConstants.ALARM_ASSIGNED) ? "assigned" : "unassigned") + .action(trigger.getActionType() == ActionType.ALARM_ASSIGNED ? "assigned" : "unassigned") .assigneeFirstName(assignee != null ? assignee.getFirstName() : null) .assigneeLastName(assignee != null ? assignee.getLastName() : null) .assigneeEmail(assignee != null ? assignee.getEmail() : null) .assigneeId(assignee != null ? assignee.getId() : null) - .userEmail(trigger.getMsg().getMetaData().getValue("userEmail")) - .userFirstName(trigger.getMsg().getMetaData().getValue("userFirstName")) - .userLastName(trigger.getMsg().getMetaData().getValue("userLastName")) + .userEmail(trigger.getUser().getEmail()) + .userFirstName(trigger.getUser().getFirstName()) + .userLastName(trigger.getUser().getLastName()) .alarmId(alarmInfo.getUuidId()) .alarmType(alarmInfo.getType()) .alarmOriginator(alarmInfo.getOriginator()) @@ -77,9 +73,4 @@ public class AlarmAssignmentTriggerProcessor implements RuleEngineMsgNotificatio return NotificationRuleTriggerType.ALARM_ASSIGNMENT; } - @Override - public Set getSupportedMsgTypes() { - return Set.of(DataConstants.ALARM_ASSIGNED, DataConstants.ALARM_UNASSIGNED); - } - } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java index cf71718f83..70024d6e09 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java @@ -15,68 +15,67 @@ */ package org.thingsboard.server.service.notification.rule.trigger; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.alarm.Alarm; -import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmCommentType; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.notification.info.AlarmCommentNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.TbMsg; -import org.thingsboard.server.common.msg.notification.trigger.RuleEngineMsgTrigger; - -import java.util.Set; +import org.thingsboard.server.common.msg.notification.trigger.AlarmCommentTrigger; +import org.thingsboard.server.dao.entity.EntityService; import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; @Service -public class AlarmCommentTriggerProcessor implements RuleEngineMsgNotificationRuleTriggerProcessor { +@RequiredArgsConstructor +public class AlarmCommentTriggerProcessor implements NotificationRuleTriggerProcessor { + + private final EntityService entityService; @Override - public boolean matchesFilter(RuleEngineMsgTrigger trigger, AlarmCommentNotificationRuleTriggerConfig triggerConfig) { - TbMsg msg = trigger.getMsg(); - if (msg.getMetaData().getValue("comment") == null) { - return false; - } - if (msg.getType().equals(DataConstants.COMMENT_UPDATED) && !triggerConfig.isNotifyOnCommentUpdate()) { + public boolean matchesFilter(AlarmCommentTrigger trigger, AlarmCommentNotificationRuleTriggerConfig triggerConfig) { + if (trigger.getActionType() == ActionType.UPDATED_COMMENT && !triggerConfig.isNotifyOnCommentUpdate()) { return false; } if (triggerConfig.isOnlyUserComments()) { - AlarmComment comment = JacksonUtil.fromString(msg.getMetaData().getValue("comment"), AlarmComment.class); - if (comment.getType() == AlarmCommentType.SYSTEM) { + if (trigger.getComment().getType() == AlarmCommentType.SYSTEM) { return false; } } - Alarm alarm = JacksonUtil.fromString(msg.getData(), Alarm.class); + Alarm alarm = trigger.getAlarm(); return emptyOrContains(triggerConfig.getAlarmTypes(), alarm.getType()) && emptyOrContains(triggerConfig.getAlarmSeverities(), alarm.getSeverity()) && (isEmpty(triggerConfig.getAlarmStatuses()) || AlarmStatusFilter.from(triggerConfig.getAlarmStatuses()).matches(alarm)); } @Override - public RuleOriginatedNotificationInfo constructNotificationInfo(RuleEngineMsgTrigger trigger) { - TbMsg msg = trigger.getMsg(); - AlarmComment comment = JacksonUtil.fromString(msg.getMetaData().getValue("comment"), AlarmComment.class); - AlarmInfo alarmInfo = JacksonUtil.fromString(msg.getData(), AlarmInfo.class); + public RuleOriginatedNotificationInfo constructNotificationInfo(AlarmCommentTrigger trigger) { + Alarm alarm = trigger.getAlarm(); + String originatorName; + if (alarm instanceof AlarmInfo) { + originatorName = ((AlarmInfo) alarm).getOriginatorName(); + } else { + originatorName = entityService.fetchEntityName(trigger.getTenantId(), alarm.getOriginator()).orElse(""); + } return AlarmCommentNotificationInfo.builder() - .comment(comment.getComment().get("text").asText()) - .action(msg.getType().equals(DataConstants.COMMENT_CREATED) ? "added" : "updated") - .userEmail(msg.getMetaData().getValue("userEmail")) - .userFirstName(msg.getMetaData().getValue("userFirstName")) - .userLastName(msg.getMetaData().getValue("userLastName")) - .alarmId(alarmInfo.getUuidId()) - .alarmType(alarmInfo.getType()) - .alarmOriginator(alarmInfo.getOriginator()) - .alarmOriginatorName(alarmInfo.getOriginatorName()) - .alarmSeverity(alarmInfo.getSeverity()) - .alarmStatus(alarmInfo.getStatus()) - .alarmCustomerId(alarmInfo.getCustomerId()) + .comment(trigger.getComment().getComment().get("text").asText()) + .action(trigger.getActionType() == ActionType.ADDED_COMMENT ? "added" : "updated") + .userEmail(trigger.getUser().getEmail()) + .userFirstName(trigger.getUser().getFirstName()) + .userLastName(trigger.getUser().getLastName()) + .alarmId(alarm.getUuidId()) + .alarmType(alarm.getType()) + .alarmOriginator(alarm.getOriginator()) + .alarmOriginatorName(originatorName) + .alarmSeverity(alarm.getSeverity()) + .alarmStatus(alarm.getStatus()) + .alarmCustomerId(alarm.getCustomerId()) .build(); } @@ -85,9 +84,4 @@ public class AlarmCommentTriggerProcessor implements RuleEngineMsgNotificationRu return NotificationRuleTriggerType.ALARM_COMMENT; } - @Override - public Set getSupportedMsgTypes() { - return Set.of(DataConstants.COMMENT_CREATED, DataConstants.COMMENT_UPDATED); - } - } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java index 6e181044c7..3188eeabb1 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java @@ -18,9 +18,7 @@ package org.thingsboard.server.service.notification.rule.trigger; import lombok.RequiredArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.info.DeviceActivityNotificationInfo; @@ -28,28 +26,22 @@ import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotifi import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.TbMsg; -import org.thingsboard.server.common.msg.notification.trigger.RuleEngineMsgTrigger; +import org.thingsboard.server.common.msg.notification.trigger.DeviceActivityTrigger; import org.thingsboard.server.service.profile.TbDeviceProfileCache; -import java.util.Set; - @Service @RequiredArgsConstructor -public class DeviceActivityTriggerProcessor implements RuleEngineMsgNotificationRuleTriggerProcessor { +public class DeviceActivityTriggerProcessor implements NotificationRuleTriggerProcessor { private final TbDeviceProfileCache deviceProfileCache; @Override - public boolean matchesFilter(RuleEngineMsgTrigger trigger, DeviceActivityNotificationRuleTriggerConfig triggerConfig) { - if (trigger.getMsg().getOriginator().getEntityType() != EntityType.DEVICE) { - return false; - } - DeviceEvent event = trigger.getMsg().getType().equals(DataConstants.ACTIVITY_EVENT) ? DeviceEvent.ACTIVE : DeviceEvent.INACTIVE; + public boolean matchesFilter(DeviceActivityTrigger trigger, DeviceActivityNotificationRuleTriggerConfig triggerConfig) { + DeviceEvent event = trigger.isActive() ? DeviceEvent.ACTIVE : DeviceEvent.INACTIVE; if (!triggerConfig.getNotifyOn().contains(event)) { return false; } - DeviceId deviceId = (DeviceId) trigger.getMsg().getOriginator(); + DeviceId deviceId = trigger.getDeviceId(); if (CollectionUtils.isNotEmpty(triggerConfig.getDevices())) { return triggerConfig.getDevices().contains(deviceId.getId()); } else if (CollectionUtils.isNotEmpty(triggerConfig.getDeviceProfiles())) { @@ -61,15 +53,14 @@ public class DeviceActivityTriggerProcessor implements RuleEngineMsgNotification } @Override - public RuleOriginatedNotificationInfo constructNotificationInfo(RuleEngineMsgTrigger trigger) { - TbMsg msg = trigger.getMsg(); + public RuleOriginatedNotificationInfo constructNotificationInfo(DeviceActivityTrigger trigger) { return DeviceActivityNotificationInfo.builder() - .eventType(trigger.getMsg().getType().equals(DataConstants.ACTIVITY_EVENT) ? "active" : "inactive") - .deviceId(msg.getOriginator().getId()) - .deviceName(msg.getMetaData().getValue("deviceName")) - .deviceType(msg.getMetaData().getValue("deviceType")) - .deviceLabel(msg.getMetaData().getValue("deviceLabel")) - .deviceCustomerId(msg.getCustomerId()) + .eventType(trigger.isActive() ? "active" : "inactive") + .deviceId(trigger.getDeviceId().getId()) + .deviceName(trigger.getDeviceName()) + .deviceType(trigger.getDeviceType()) + .deviceLabel(trigger.getDeviceLabel()) + .deviceCustomerId(trigger.getCustomerId()) .build(); } @@ -78,9 +69,4 @@ public class DeviceActivityTriggerProcessor implements RuleEngineMsgNotification return NotificationRuleTriggerType.DEVICE_ACTIVITY; } - @Override - public Set getSupportedMsgTypes() { - return Set.of(DataConstants.ACTIVITY_EVENT, DataConstants.INACTIVITY_EVENT); - } - } diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index e33e501fbc..337d607fac 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -31,7 +31,6 @@ import org.apache.commons.lang3.tuple.Pair; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardExecutors; @@ -63,6 +62,8 @@ import org.thingsboard.server.common.data.query.EntityListFilter; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.trigger.DeviceActivityTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; @@ -70,12 +71,10 @@ import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.sql.query.EntityQueryRepository; -import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.dao.util.DbTypeInfoComponent; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.discovery.PartitionService; -import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.partition.AbstractPartitionBasedService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; @@ -158,6 +157,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService msgTypeToTriggerType; // set on init by DefaultNotificationRuleProcessor + private final AlarmInfo alarmInfo; + private final ActionType actionType; + private final User user; @Override - public NotificationRuleTriggerType getType() { - return msgTypeToTriggerType != null ? msgTypeToTriggerType.get(msg.getType()) : null; + public EntityId getOriginatorEntityId() { + return alarmInfo.getOriginator(); } @Override - public EntityId getOriginatorEntityId() { - return msg.getOriginator(); + public NotificationRuleTriggerType getType() { + return NotificationRuleTriggerType.ALARM_ASSIGNMENT; } } diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmCommentTrigger.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmCommentTrigger.java new file mode 100644 index 0000000000..d0b3bdd5de --- /dev/null +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmCommentTrigger.java @@ -0,0 +1,48 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.msg.notification.trigger; + +import lombok.Builder; +import lombok.Data; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmComment; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; + +@Data +@Builder +public class AlarmCommentTrigger implements NotificationRuleTrigger { + + private final TenantId tenantId; + private final AlarmComment comment; + private final Alarm alarm; + private final ActionType actionType; + private final User user; + + @Override + public NotificationRuleTriggerType getType() { + return NotificationRuleTriggerType.ALARM_COMMENT; + } + + @Override + public EntityId getOriginatorEntityId() { + return alarm.getId(); + } + +} diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/ApiUsageLimitTrigger.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/ApiUsageLimitTrigger.java index 368a16712c..f21d3077ca 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/ApiUsageLimitTrigger.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/ApiUsageLimitTrigger.java @@ -36,11 +36,6 @@ public class ApiUsageLimitTrigger implements NotificationRuleTrigger { return NotificationRuleTriggerType.API_USAGE_LIMIT; } - @Override - public TenantId getTenantId() { - return tenantId; - } - @Override public EntityId getOriginatorEntityId() { return tenantId; diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/DeviceActivityTrigger.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/DeviceActivityTrigger.java new file mode 100644 index 0000000000..b426b6674b --- /dev/null +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/DeviceActivityTrigger.java @@ -0,0 +1,49 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.msg.notification.trigger; + +import lombok.Builder; +import lombok.Data; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; + +@Data +@Builder +public class DeviceActivityTrigger implements NotificationRuleTrigger { + + private final TenantId tenantId; + private final CustomerId customerId; + private final DeviceId deviceId; + private final boolean active; + + private final String deviceName; + private final String deviceType; + private final String deviceLabel; + + @Override + public EntityId getOriginatorEntityId() { + return deviceId; + } + + @Override + public NotificationRuleTriggerType getType() { + return NotificationRuleTriggerType.DEVICE_ACTIVITY; + } + +} From 184a554d08b2980258b33f2d2ee146a1337dd967 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 2 Jun 2023 15:00:03 +0300 Subject: [PATCH 116/207] More tests for notification rules; fix unstable tests --- .../AbstractNotificationApiTest.java | 38 ++++- .../notification/NotificationRuleApiTest.java | 154 +++++++++++++++++- 2 files changed, 183 insertions(+), 9 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java index ac3857dbdf..f45882e416 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.notification; import com.fasterxml.jackson.core.type.TypeReference; import org.apache.commons.lang3.RandomStringUtils; +import org.junit.After; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.util.Pair; @@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.NotificationRequestId; import org.thingsboard.server.common.data.id.NotificationTargetId; import org.thingsboard.server.common.data.id.NotificationTemplateId; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.notification.Notification; @@ -43,6 +45,7 @@ import org.thingsboard.server.common.data.notification.settings.NotificationSett import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig; import org.thingsboard.server.common.data.notification.targets.platform.UserListFilter; +import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter; import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate; import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; @@ -54,6 +57,10 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.notification.NotificationRequestService; +import org.thingsboard.server.dao.notification.NotificationRuleService; +import org.thingsboard.server.dao.notification.NotificationTargetService; +import org.thingsboard.server.dao.notification.NotificationTemplateService; import java.net.URISyntaxException; import java.util.Arrays; @@ -72,21 +79,40 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest @MockBean protected SlackService slackService; - @Autowired protected MailService mailService; + @Autowired + protected NotificationRuleService notificationRuleService; + @Autowired + protected NotificationTemplateService notificationTemplateService; + @Autowired + protected NotificationTargetService notificationTargetService; + @Autowired + protected NotificationRequestService notificationRequestService; + public static final String DEFAULT_NOTIFICATION_SUBJECT = "Just a test"; public static final NotificationType DEFAULT_NOTIFICATION_TYPE = NotificationType.GENERAL; + @After + public void afterEach() { + notificationRequestService.deleteNotificationRequestsByTenantId(TenantId.SYS_TENANT_ID); + notificationRuleService.deleteNotificationRulesByTenantId(TenantId.SYS_TENANT_ID); + notificationTemplateService.deleteNotificationTemplatesByTenantId(TenantId.SYS_TENANT_ID); + notificationTargetService.deleteNotificationTargetsByTenantId(TenantId.SYS_TENANT_ID); + } + protected NotificationTarget createNotificationTarget(UserId... usersIds) { - NotificationTarget notificationTarget = new NotificationTarget(); - notificationTarget.setTenantId(tenantId); - notificationTarget.setName("Users " + List.of(usersIds)); - PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig(); UserListFilter filter = new UserListFilter(); filter.setUsersIds(DaoUtil.toUUIDs(List.of(usersIds))); - targetConfig.setUsersFilter(filter); + return createNotificationTarget(filter); + } + + protected NotificationTarget createNotificationTarget(UsersFilter usersFilter) { + NotificationTarget notificationTarget = new NotificationTarget(); + notificationTarget.setName(usersFilter.toString()); + PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig(); + targetConfig.setUsersFilter(usersFilter); notificationTarget.setConfiguration(targetConfig); return saveNotificationTarget(notificationTarget); } diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java index 044428e270..6c4413d1e7 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java @@ -17,12 +17,14 @@ package org.thingsboard.server.service.notification; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.BooleanNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Before; import org.junit.Test; import org.junit.function.ThrowingRunnable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.data.util.Pair; +import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -31,10 +33,15 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.UpdateMessage; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmComment; +import org.thingsboard.server.common.data.alarm.AlarmCommentType; import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.asset.Asset; +import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration; +import org.thingsboard.server.common.data.device.data.DefaultDeviceTransportConfiguration; +import org.thingsboard.server.common.data.device.data.DeviceData; import org.thingsboard.server.common.data.device.profile.AlarmCondition; import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter; import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey; @@ -42,6 +49,8 @@ import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType; import org.thingsboard.server.common.data.device.profile.AlarmRule; import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec; +import org.thingsboard.server.common.data.id.AlarmId; +import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.notification.Notification; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.NotificationRequest; @@ -52,8 +61,11 @@ import org.thingsboard.server.common.data.notification.rule.DefaultNotificationR import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig.AlarmAction; +import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionNotificationRuleTriggerConfig; @@ -68,13 +80,16 @@ import org.thingsboard.server.common.data.query.FilterPredicateValue; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.common.msg.notification.trigger.NewPlatformVersionTrigger; +import org.thingsboard.server.dao.notification.DefaultNotifications; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; -import org.thingsboard.server.queue.notification.NotificationRuleProcessor; +import org.thingsboard.server.service.notification.rule.cache.DefaultNotificationRulesCache; +import org.thingsboard.server.service.state.DeviceStateService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; import java.util.ArrayList; @@ -94,8 +109,15 @@ import static org.assertj.core.api.Assertions.offset; import static org.assertj.core.api.InstanceOfAssertFactories.type; import static org.awaitility.Awaitility.await; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig.Action.ASSIGNED; +import static org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig.Action.UNASSIGNED; +import static org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent.ACTIVE; +import static org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent.INACTIVE; @DaoSqlTest +@TestPropertySource(properties = { + "transport.http.enabled=true" +}) public class NotificationRuleApiTest extends AbstractNotificationApiTest { @SpyBean @@ -108,6 +130,12 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { private RuleChainService ruleChainService; @Autowired private NotificationRuleProcessor notificationRuleProcessor; + @Autowired + private DefaultNotifications defaultNotifications; + @Autowired + private DefaultNotificationRulesCache notificationRulesCache; + @Autowired + private DeviceStateService deviceStateService; @Before public void beforeEach() throws Exception { @@ -297,7 +325,9 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { notification = getWsClient().getLastDataUpdate().getUpdate(); assertThat(notification.getSubject()).isEqualTo("critical alarm '" + alarmType + "' is CLEARED_UNACK"); - assertThat(findNotificationRequests(EntityType.ALARM).getData()).filteredOn(NotificationRequest::isScheduled).isEmpty(); + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + assertThat(findNotificationRequests(EntityType.ALARM).getData()).filteredOn(NotificationRequest::isScheduled).isEmpty(); + }); } @Test @@ -370,6 +400,122 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { }); } + @Test + public void testNotificationRuleProcessing_alarmAssignment() throws Exception { + AlarmAssignmentNotificationRuleTriggerConfig triggerConfig = AlarmAssignmentNotificationRuleTriggerConfig.builder() + .alarmTypes(Set.of("test")) + .notifyOn(Set.of(ASSIGNED, UNASSIGNED)) + .build(); + NotificationTarget target = createNotificationTarget(tenantAdminUserId); + String template = "${userEmail} ${action} alarm on ${alarmOriginatorEntityType} '${alarmOriginatorName}'. Assignee: ${assigneeEmail}"; + createNotificationRule(triggerConfig, "Test", template, target.getId()); + + Device device = createDevice("Device A", "123"); + Alarm alarm = Alarm.builder() + .tenantId(tenantId) + .originator(device.getId()) + .cleared(false) + .acknowledged(false) + .severity(AlarmSeverity.CRITICAL) + .type("test") + .startTs(System.currentTimeMillis()) + .build(); + alarm = doPost("/api/alarm", alarm, Alarm.class); + AlarmId alarmId = alarm.getId(); + + checkNotificationAfter(() -> { + doPost("/api/alarm/" + alarmId + "/assign/" + tenantAdminUserId).andExpect(status().isOk()); + }, notification -> { + assertThat(notification.getText()).isEqualTo( + TENANT_ADMIN_EMAIL + " assigned alarm on Device 'Device A'. Assignee: " + TENANT_ADMIN_EMAIL + ); + }); + + checkNotificationAfter(() -> { + doDelete("/api/alarm/" + alarmId + "/assign").andExpect(status().isOk()); + }, notification -> { + assertThat(notification.getText()).isEqualTo( + TENANT_ADMIN_EMAIL + " unassigned alarm on Device 'Device A'. Assignee: " + ); + }); + } + + @Test + public void testNotificationRuleProcessing_alarmComment() throws Exception { + AlarmCommentNotificationRuleTriggerConfig triggerConfig = AlarmCommentNotificationRuleTriggerConfig.builder() + .alarmTypes(Set.of("test")) + .onlyUserComments(true) + .notifyOnCommentUpdate(true) + .build(); + NotificationTarget target = createNotificationTarget(tenantAdminUserId); + String template = "${userEmail} ${action} comment on alarm ${alarmType}: ${comment}"; + createNotificationRule(triggerConfig, "Test", template, target.getId()); + + Device device = createDevice("Device A", "123"); + Alarm alarm = Alarm.builder() + .tenantId(tenantId) + .originator(device.getId()) + .cleared(false) + .acknowledged(false) + .severity(AlarmSeverity.CRITICAL) + .type("test") + .startTs(System.currentTimeMillis()) + .build(); + alarm = doPost("/api/alarm", alarm, Alarm.class); + AlarmId alarmId = alarm.getId(); + + AlarmComment comment = checkNotificationAfter(() -> { + return doPost("/api/alarm/" + alarmId + "/comment", + AlarmComment.builder() + .type(AlarmCommentType.OTHER) + .comment(JacksonUtil.newObjectNode() + .put("text", "this is bad")) + .build(), AlarmComment.class); + }, (notification, r) -> { + assertThat(notification.getText()).isEqualTo( + TENANT_ADMIN_EMAIL + " added comment on alarm test: this is bad" + ); + }); + + checkNotificationAfter(() -> { + ((ObjectNode) comment.getComment()).put("text", "this is very bad"); + doPost("/api/alarm/" + alarmId + "/comment", comment); + }, notification -> { + assertThat(notification.getText()).isEqualTo( + TENANT_ADMIN_EMAIL + " updated comment on alarm test: this is very bad" + ); + }); + } + + @Test + public void testNotificationRuleProcessing_deviceActivity() throws Exception { + DeviceActivityNotificationRuleTriggerConfig triggerConfig = DeviceActivityNotificationRuleTriggerConfig.builder() + .notifyOn(Set.of(ACTIVE, INACTIVE)) + .build(); + NotificationTarget target = createNotificationTarget(tenantAdminUserId); + String template = "Device ${deviceName} (${deviceLabel}) of type ${deviceType} is now ${eventType}"; + createNotificationRule(triggerConfig, "Test", template, target.getId()); + + Device device = new Device(); + device.setName("A"); + device.setLabel("Test Device A"); + device.setType("test"); + DeviceData deviceData = new DeviceData(); + deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration()); + deviceData.setConfiguration(new DefaultDeviceConfiguration()); + device.setDeviceData(deviceData); + device = doPost("/api/device", device, Device.class); + DeviceId deviceId = device.getId(); + + checkNotificationAfter(() -> { + deviceStateService.onDeviceActivity(tenantId, deviceId, System.currentTimeMillis()); + }, notification -> { + assertThat(notification.getText()).isEqualTo( + "Device A (Test Device A) of type test is now active" + ); + }); + } + @Test public void testNotificationRuleInfo() throws Exception { NotificationDeliveryMethod[] deliveryMethods = {NotificationDeliveryMethod.WEB, NotificationDeliveryMethod.EMAIL}; @@ -477,6 +623,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { triggerConfig.setEntityTypes(Set.of(EntityType.DEVICE)); triggerConfig.setCreated(true); NotificationRule rule = createNotificationRule(triggerConfig, "Created", "Created", createNotificationTarget(tenantAdminUserId).getId()); + notificationRulesCache.evict(tenantId); assertThat(getMyNotifications(false, 100)).size().isZero(); createDevice("Device 1", "default", "111"); @@ -487,6 +634,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { rule.setEnabled(false); saveNotificationRule(rule); + notificationRulesCache.evict(tenantId); createDevice("Device 2", "default", "222"); TimeUnit.SECONDS.sleep(5); @@ -494,7 +642,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { rule.setEnabled(true); saveNotificationRule(rule); - TimeUnit.SECONDS.sleep(2); // for rule update event to reach rules cache + notificationRulesCache.evict(tenantId); createDevice("Device 3", "default", "333"); await().atMost(30, TimeUnit.SECONDS) From 2f560315d16b759fd985a979a4eba84c829a4c00 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 2 Jun 2023 15:09:09 +0300 Subject: [PATCH 117/207] Exceeded rate limits notifications; their deduplication; refactoring --- .../config/RateLimitProcessingFilter.java | 6 +- .../server/controller/AuthController.java | 2 +- .../controller/plugin/TbWebSocketHandler.java | 2 +- .../install/ThingsboardInstallService.java | 1 + .../DefaultSystemDataLoaderService.java | 5 + .../install/SystemDataLoaderService.java | 2 + .../DefaultNotificationCenter.java | 2 +- .../DefaultNotificationRuleProcessor.java | 2 +- .../trigger/RateLimitsTriggerProcessor.java | 71 ++++++++++ .../auth/mfa/DefaultTwoFactorAuthService.java | 2 +- .../DefaultEntitiesExportImportService.java | 2 +- .../src/main/resources/thingsboard.yml | 3 + .../service/limits/RateLimitServiceTest.java | 10 +- .../MockNotificationSettingsService.java | 2 +- .../notification/NotificationRuleApiTest.java | 129 +++++++++++++++++- .../NotificationSettingsService.java | 2 + .../NotificationTargetService.java | 3 + .../server/common/data/limit/LimitedApi.java | 70 ++++++++++ .../data/notification/NotificationType.java | 3 +- .../info/RateLimitsNotificationInfo.java | 59 ++++++++ .../NotificationRuleTriggerConfig.java | 1 + .../trigger/NotificationRuleTriggerType.java | 3 +- ...teLimitsNotificationRuleTriggerConfig.java | 45 ++++++ .../trigger/RateLimitsTrigger.java | 62 +++++++++ .../provider/AwsSqsTransportQueueFactory.java | 6 + .../InMemoryTbTransportQueueFactory.java | 6 + .../KafkaTbTransportQueueFactory.java | 12 ++ .../provider/PubSubTransportQueueFactory.java | 7 + .../RabbitMqTransportQueueFactory.java | 7 + .../ServiceBusTransportQueueFactory.java | 7 + .../provider/TbTransportQueueFactory.java | 3 + .../TbTransportQueueProducerProvider.java | 4 +- .../DefaultTransportRateLimitService.java | 27 ++-- .../service/DefaultTransportService.java | 15 +- .../DefaultNotificationSettingsService.java | 32 +++++ .../DefaultNotificationTargetService.java | 6 + .../notification/DefaultNotifications.java | 52 +++++++ .../notification/NotificationTargetDao.java | 3 + .../JpaNotificationTargetDao.java | 6 + .../util/AbstractBufferedRateExecutor.java | 2 +- .../util/limits/DefaultRateLimitService.java | 22 ++- .../server/dao/util/limits/LimitedApi.java | 67 --------- .../dao/util/limits/RateLimitService.java | 1 + .../src/main/resources/tb-vc-executor.yml | 7 + .../src/main/resources/tb-coap-transport.yml | 7 + .../src/main/resources/tb-http-transport.yml | 7 + .../src/main/resources/tb-lwm2m-transport.yml | 7 + .../src/main/resources/tb-mqtt-transport.yml | 7 + .../src/main/resources/tb-snmp-transport.yml | 7 + 49 files changed, 709 insertions(+), 107 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/limit/LimitedApi.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RateLimitsNotificationInfo.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsNotificationRuleTriggerConfig.java create mode 100644 common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RateLimitsTrigger.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/limits/LimitedApi.java diff --git a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java index 89f9b751fd..2ecc8590b8 100644 --- a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java @@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.exception.TenantProfileNotFoundException; import org.thingsboard.server.common.msg.tools.TbRateLimitsException; import org.thingsboard.server.exception.ThingsboardErrorResponseHandler; -import org.thingsboard.server.dao.util.limits.LimitedApi; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.service.security.model.SecurityUser; @@ -49,7 +49,7 @@ public class RateLimitProcessingFilter extends OncePerRequestFilter { SecurityUser user = getCurrentUser(); if (user != null && !user.isSystemAdmin()) { try { - if (!rateLimitService.checkRateLimit(LimitedApi.REST_REQUESTS, user.getTenantId())) { + if (!rateLimitService.checkRateLimit(LimitedApi.REST_REQUESTS_PER_TENANT, user.getTenantId())) { rateLimitExceeded(EntityType.TENANT, response); return; } @@ -60,7 +60,7 @@ public class RateLimitProcessingFilter extends OncePerRequestFilter { } if (user.isCustomerUser()) { - if (!rateLimitService.checkRateLimit(LimitedApi.REST_REQUESTS, user.getTenantId(), user.getCustomerId())) { + if (!rateLimitService.checkRateLimit(LimitedApi.REST_REQUESTS_PER_CUSTOMER, user.getTenantId(), user.getCustomerId())) { rateLimitExceeded(EntityType.CUSTOMER, response); return; } diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index 566b6900a4..4512334d61 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -49,7 +49,7 @@ import org.thingsboard.server.common.data.security.model.JwtPair; import org.thingsboard.server.common.data.security.model.SecuritySettings; import org.thingsboard.server.common.data.security.model.UserPasswordPolicy; import org.thingsboard.server.queue.util.TbCoreComponent; -import org.thingsboard.server.dao.util.limits.LimitedApi; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails; import org.thingsboard.server.service.security.model.ActivateUserRequest; diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java index bc51c5fdd1..91583136f6 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java @@ -36,7 +36,7 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.config.WebSocketConfiguration; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; -import org.thingsboard.server.dao.util.limits.LimitedApi; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 51d7435f0e..c6b9fe08a0 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -260,6 +260,7 @@ public class ThingsboardInstallService { case "3.5.1": log.info("Upgrading ThingsBoard from version 3.5.1 to 3.5.2 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.5.1"); + systemDataLoaderService.updateDefaultNotificationConfigs(); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 497627f629..7965824274 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -709,4 +709,9 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); } + @Override + public void updateDefaultNotificationConfigs() { + notificationSettingsService.updateDefaultNotificationConfigs(TenantId.SYS_TENANT_ID); + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java index fb6b28592c..08de12da78 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SystemDataLoaderService.java @@ -41,4 +41,6 @@ public interface SystemDataLoaderService { void createDefaultNotificationConfigs(); + void updateDefaultNotificationConfigs(); + } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java index 7215776170..cb77cc0948 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java @@ -28,6 +28,7 @@ import org.thingsboard.server.common.data.id.NotificationRuleId; import org.thingsboard.server.common.data.id.NotificationTargetId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.notification.AlreadySentException; import org.thingsboard.server.common.data.notification.Notification; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; @@ -56,7 +57,6 @@ import org.thingsboard.server.dao.notification.NotificationService; import org.thingsboard.server.dao.notification.NotificationSettingsService; import org.thingsboard.server.dao.notification.NotificationTargetService; import org.thingsboard.server.dao.notification.NotificationTemplateService; -import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.common.TbProtoQueueMsg; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java index 71a59026a2..3a5ae8339d 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java @@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.NotificationRequestId; import org.thingsboard.server.common.data.id.NotificationRuleId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.notification.NotificationRequest; import org.thingsboard.server.common.data.notification.NotificationRequestConfig; import org.thingsboard.server.common.data.notification.NotificationRequestStatus; @@ -46,7 +47,6 @@ import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTr import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.dao.notification.NotificationRequestService; -import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.service.executors.NotificationExecutorService; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java new file mode 100644 index 0000000000..910ef4866f --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java @@ -0,0 +1,71 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.notification.rule.trigger; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.notification.info.RateLimitsNotificationInfo; +import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.util.CollectionsUtil; +import org.thingsboard.server.common.msg.notification.trigger.RateLimitsTrigger; +import org.thingsboard.server.dao.entity.EntityService; +import org.thingsboard.server.dao.tenant.TenantService; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class RateLimitsTriggerProcessor implements NotificationRuleTriggerProcessor { + + private final TenantService tenantService; + private final EntityService entityService; + + @Override + public boolean matchesFilter(RateLimitsTrigger trigger, RateLimitsNotificationRuleTriggerConfig triggerConfig) { + return trigger.getLimitLevel() != null && trigger.getApi().getLabel() != null && + CollectionsUtil.emptyOrContains(triggerConfig.getApis(), trigger.getApi()); + } + + @Override + public RuleOriginatedNotificationInfo constructNotificationInfo(RateLimitsTrigger trigger) { + EntityId limitLevel = trigger.getLimitLevel(); + String tenantName = tenantService.findTenantById(trigger.getTenantId()).getName(); + String limitLevelEntityName = null; + if (limitLevel instanceof TenantId) { + limitLevelEntityName = tenantName; + } else if (limitLevel != null) { + limitLevelEntityName = Optional.ofNullable(trigger.getLimitLevelEntityName()) + .orElseGet(() -> entityService.fetchEntityName(trigger.getTenantId(), limitLevel).orElse(null)); + } + return RateLimitsNotificationInfo.builder() + .tenantId(trigger.getTenantId()) + .tenantName(tenantName) + .api(trigger.getApi()) + .limitLevel(limitLevel) + .limitLevelEntityName(limitLevelEntityName) + .build(); + } + + @Override + public NotificationRuleTriggerType getTriggerType() { + return NotificationRuleTriggerType.RATE_LIMITS; + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java index a58c801583..08717986bf 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.security.model.mfa.account.TwoFaAccoun import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; import org.thingsboard.server.dao.user.UserService; -import org.thingsboard.server.dao.util.limits.LimitedApi; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java index c8f8f945f9..3b37b0fe26 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java @@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.util.ThrowingRunnable; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.queue.util.TbCoreComponent; -import org.thingsboard.server.dao.util.limits.LimitedApi; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.sync.ie.exporting.EntityExportService; diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 392587c869..81589d2bce 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -1266,6 +1266,9 @@ notification_system: NEW_PLATFORM_VERSION: # In milliseconds, infinitely by default deduplication_duration: "${NEW_PLATFORM_VERSION_NOTIFICATION_RULE_DEDUPLICATION_DURATION:0}" + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" management: endpoints: diff --git a/application/src/test/java/org/thingsboard/server/service/limits/RateLimitServiceTest.java b/application/src/test/java/org/thingsboard/server/service/limits/RateLimitServiceTest.java index 05ee66f327..c56adb5fd5 100644 --- a/application/src/test/java/org/thingsboard/server/service/limits/RateLimitServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/limits/RateLimitServiceTest.java @@ -24,11 +24,12 @@ import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.NotificationRuleId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.util.limits.DefaultRateLimitService; -import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import java.util.List; @@ -37,6 +38,7 @@ import java.util.UUID; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; @@ -50,7 +52,7 @@ public class RateLimitServiceTest { @Before public void beforeEach() { tenantProfileCache = Mockito.mock(TbTenantProfileCache.class); - rateLimitService = new DefaultRateLimitService(tenantProfileCache, 60, 100); + rateLimitService = new DefaultRateLimitService(tenantProfileCache, mock(NotificationRuleProcessor.class), 60, 100); tenantId = new TenantId(UUID.randomUUID()); } @@ -73,14 +75,14 @@ public class RateLimitServiceTest { LimitedApi.ENTITY_EXPORT, LimitedApi.ENTITY_IMPORT, LimitedApi.NOTIFICATION_REQUESTS, - LimitedApi.REST_REQUESTS, + LimitedApi.REST_REQUESTS_PER_CUSTOMER, LimitedApi.CASSANDRA_QUERIES )) { testRateLimits(limitedApi, max, tenantId); } CustomerId customerId = new CustomerId(UUID.randomUUID()); - testRateLimits(LimitedApi.REST_REQUESTS, max, customerId); + testRateLimits(LimitedApi.REST_REQUESTS_PER_CUSTOMER, max, customerId); NotificationRuleId notificationRuleId = new NotificationRuleId(UUID.randomUUID()); testRateLimits(LimitedApi.NOTIFICATION_REQUESTS_PER_RULE, max, notificationRuleId); diff --git a/application/src/test/java/org/thingsboard/server/service/notification/MockNotificationSettingsService.java b/application/src/test/java/org/thingsboard/server/service/notification/MockNotificationSettingsService.java index a1cc82fd5a..a49f8dc8cb 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/MockNotificationSettingsService.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/MockNotificationSettingsService.java @@ -26,7 +26,7 @@ import org.thingsboard.server.dao.settings.AdminSettingsService; public class MockNotificationSettingsService extends DefaultNotificationSettingsService { public MockNotificationSettingsService(AdminSettingsService adminSettingsService) { - super(adminSettingsService, null, null); + super(adminSettingsService, null, null, null); } @Override diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java index 6c4413d1e7..4155e2a4b3 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java @@ -51,12 +51,15 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.notification.Notification; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.NotificationRequest; import org.thingsboard.server.common.data.notification.NotificationRequestInfo; import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.info.AlarmNotificationInfo; +import org.thingsboard.server.common.data.notification.info.RateLimitsNotificationInfo; import org.thingsboard.server.common.data.notification.rule.DefaultNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRule; @@ -70,7 +73,10 @@ import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimi import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; +import org.thingsboard.server.common.data.notification.targets.platform.AffectedTenantAdministratorsFilter; +import org.thingsboard.server.common.data.notification.targets.platform.SystemAdministratorsFilter; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -82,12 +88,13 @@ import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.common.msg.notification.trigger.NewPlatformVersionTrigger; +import org.thingsboard.server.common.msg.notification.trigger.RateLimitsTrigger; import org.thingsboard.server.dao.notification.DefaultNotifications; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.service.DaoSqlTest; -import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.service.notification.rule.DefaultNotificationRuleProcessor; import org.thingsboard.server.service.notification.rule.cache.DefaultNotificationRulesCache; import org.thingsboard.server.service.state.DeviceStateService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; @@ -103,6 +110,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.offset; @@ -116,7 +124,8 @@ import static org.thingsboard.server.common.data.notification.rule.trigger.Devic @DaoSqlTest @TestPropertySource(properties = { - "transport.http.enabled=true" + "transport.http.enabled=true", + "notification_system.rules.trigger_types_configs.RATE_LIMITS.deduplication_duration=10000" }) public class NotificationRuleApiTest extends AbstractNotificationApiTest { @@ -400,6 +409,60 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { }); } + @Test + public void testNotificationRuleProcessing_exceededRateLimits() throws Exception { + loginSysAdmin(); + NotificationTarget sysadmins = createNotificationTarget(new SystemAdministratorsFilter()); + NotificationTarget affectedTenantAdmins = createNotificationTarget(new AffectedTenantAdministratorsFilter()); + defaultNotifications.create(TenantId.SYS_TENANT_ID, DefaultNotifications.exceededRateLimitsForSysadmin, sysadmins.getId()); + defaultNotifications.create(TenantId.SYS_TENANT_ID, DefaultNotifications.exceededRateLimits, affectedTenantAdmins.getId()); + defaultNotifications.create(TenantId.SYS_TENANT_ID, DefaultNotifications.exceededPerEntityRateLimits, affectedTenantAdmins.getId()); + notificationRulesCache.evict(TenantId.SYS_TENANT_ID); + + int n = 10; + updateDefaultTenantProfile(profileConfiguration -> { + profileConfiguration.setTenantEntityExportRateLimit(n + ":600"); + profileConfiguration.setCustomerServerRestLimitsConfiguration(n + ":600"); + profileConfiguration.setTenantNotificationRequestsPerRuleRateLimit(n + ":600"); + profileConfiguration.setTransportDeviceTelemetryMsgRateLimit(n + ":600"); + }); + loginTenantAdmin(); + NotificationRule rule = createNotificationRule(AlarmCommentNotificationRuleTriggerConfig.builder() + .alarmTypes(Set.of("weklfjkwefa")) + .build(), "Test", "Test", createNotificationTarget(tenantAdminUserId).getId()); + for (int i = 1; i <= n * 2; i++) { + rateLimitService.checkRateLimit(LimitedApi.ENTITY_EXPORT, tenantId); + rateLimitService.checkRateLimit(LimitedApi.REST_REQUESTS_PER_CUSTOMER, tenantId, customerId); + rateLimitService.checkRateLimit(LimitedApi.NOTIFICATION_REQUESTS_PER_RULE, tenantId, rule.getId()); + } + + loginTenantAdmin(); + List notifications = await().atMost(30, TimeUnit.SECONDS) + .until(() -> getMyNotifications(true, 10), list -> list.size() == 3); + assertThat(notifications).allSatisfy(notification -> { + assertThat(notification.getSubject()).isEqualTo("Rate limits exceeded"); + }); + assertThat(notifications).anySatisfy(notification -> { + assertThat(notification.getText()).isEqualTo("Rate limits for entity version creation exceeded"); + }); + assertThat(notifications).anySatisfy(notification -> { + assertThat(notification.getText()).isEqualTo("Rate limits for REST API requests per customer " + + "exceeded for 'Customer'"); + }); + assertThat(notifications).anySatisfy(notification -> { + assertThat(notification.getText()).isEqualTo("Rate limits for notification requests " + + "per rule exceeded for '" + rule.getName() + "'"); + }); + + loginSysAdmin(); + notifications = await().atMost(30, TimeUnit.SECONDS) + .until(() -> getMyNotifications(true, 10), list -> list.size() == 1); + assertThat(notifications).allSatisfy(notification -> { + assertThat(notification.getSubject()).isEqualTo("Rate limits exceeded for tenant " + TEST_TENANT_NAME); + }); + assertThat(notifications.get(0).getText()).isEqualTo("Rate limits for entity version creation exceeded"); + } + @Test public void testNotificationRuleProcessing_alarmAssignment() throws Exception { AlarmAssignmentNotificationRuleTriggerConfig triggerConfig = AlarmAssignmentNotificationRuleTriggerConfig.builder() @@ -617,6 +680,68 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { }); } + @Test + public void testNotificationsDeduplication_exceededRateLimits() throws Exception { + RateLimitsNotificationRuleTriggerConfig triggerConfig = new RateLimitsNotificationRuleTriggerConfig(); + triggerConfig.setApis(Set.of(LimitedApi.ENTITY_EXPORT, LimitedApi.TRANSPORT_MESSAGES_PER_DEVICE)); + + loginSysAdmin(); + NotificationTarget target = createNotificationTarget(tenantAdminUserId); + NotificationRule rule = createNotificationRule(triggerConfig, "Test 1", "Test", target.getId()); + + int n = 5; + updateDefaultTenantProfile(profileConfiguration -> { + profileConfiguration.setTenantEntityExportRateLimit(n + ":600"); + profileConfiguration.setTransportDeviceTelemetryMsgRateLimit(n + ":800"); + }); + + RateLimitsTrigger expectedTrigger = RateLimitsTrigger.builder() + .tenantId(tenantId) + .api(LimitedApi.ENTITY_EXPORT) + .limitLevel(tenantId) + .build(); + assertThat(DefaultNotificationRuleProcessor.getDeduplicationKey(expectedTrigger, rule)) + .isEqualTo("RATE_LIMITS:TENANT:" + tenantId + ":ENTITY_EXPORT_" + + target.getId() + ":ENTITY_EXPORT,TRANSPORT_MESSAGES_PER_DEVICE"); + + loginTenantAdmin(); + getWsClient().subscribeForUnreadNotifications(10).waitForReply(); + getWsClient().registerWaitForUpdate(2); + Device device = createDevice("Test", "Test"); + for (int i = 1; i <= n + 1; i++) { + rateLimitService.checkRateLimit(LimitedApi.ENTITY_EXPORT, tenantId); + doPost("/api/v1/" + device.getName() + "/telemetry", "{\"dp1\":123}", String.class); + } + int expectedNotificationsCount1 = 2; + getWsClient().waitForUpdate(true); + List notifications1 = getMyNotifications(true, 10); + assertThat(notifications1).size().isEqualTo(expectedNotificationsCount1); + assertThat(notifications1) + .anyMatch(notification -> ((RateLimitsNotificationInfo) notification.getInfo()).getApi() == LimitedApi.ENTITY_EXPORT) + .anyMatch(notification -> ((RateLimitsNotificationInfo) notification.getInfo()).getApi() == LimitedApi.TRANSPORT_MESSAGES_PER_DEVICE); + + getWsClient().registerWaitForUpdate(2); + for (int i = 0; i < 10; i++) { + rateLimitService.checkRateLimit(LimitedApi.ENTITY_EXPORT, tenantId); + doPost("/api/v1/" + device.getName() + "/telemetry", "{\"dp1\":123}", String.class); + } + assertThat(getWsClient().waitForUpdate(5000)).isNull(); + + int deduplicationDuration = 10000; // configured in TestPropertySource above + await().atLeast(2, TimeUnit.SECONDS) + .atMost(deduplicationDuration, TimeUnit.MILLISECONDS) + .untilAsserted(() -> { + rateLimitService.checkRateLimit(LimitedApi.ENTITY_EXPORT, tenantId); + doPost("/api/v1/" + device.getName() + "/telemetry", "{\"dp1\":123}", String.class); + + Map notifications2 = getMyNotifications(true, 10).stream() + .map(notification -> (RateLimitsNotificationInfo) notification.getInfo()) + .collect(Collectors.groupingBy(RateLimitsNotificationInfo::getApi, Collectors.counting())); + assertThat(notifications2.get(LimitedApi.ENTITY_EXPORT)).isEqualTo(2); + assertThat(notifications2.get(LimitedApi.TRANSPORT_MESSAGES_PER_DEVICE)).isEqualTo(2); + }); + } + @Test public void testNotificationRuleDisabling() throws Exception { EntityActionNotificationRuleTriggerConfig triggerConfig = new EntityActionNotificationRuleTriggerConfig(); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationSettingsService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationSettingsService.java index 46eb5ca54e..a5433915b3 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationSettingsService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationSettingsService.java @@ -26,4 +26,6 @@ public interface NotificationSettingsService { void createDefaultNotificationConfigs(TenantId tenantId); + void updateDefaultNotificationConfigs(TenantId tenantId); + } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationTargetService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationTargetService.java index 05299c1675..bd442f6bb6 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationTargetService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationTargetService.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig; +import org.thingsboard.server.common.data.notification.targets.platform.UsersFilterType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; @@ -40,6 +41,8 @@ public interface NotificationTargetService { List findNotificationTargetsByTenantIdAndIds(TenantId tenantId, List ids); + List findNotificationTargetsByTenantIdAndUsersFilterType(TenantId tenantId, UsersFilterType filterType); + PageData findRecipientsForNotificationTarget(TenantId tenantId, CustomerId customerId, NotificationTargetId targetId, PageLink pageLink); PageData findRecipientsForNotificationTargetConfig(TenantId tenantId, PlatformUsersNotificationTargetConfig targetConfig, PageLink pageLink); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/limit/LimitedApi.java b/common/data/src/main/java/org/thingsboard/server/common/data/limit/LimitedApi.java new file mode 100644 index 0000000000..e709ac596e --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/limit/LimitedApi.java @@ -0,0 +1,70 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.limit; + +import lombok.Getter; +import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; + +import java.util.Optional; +import java.util.function.Function; + +public enum LimitedApi { + + ENTITY_EXPORT(DefaultTenantProfileConfiguration::getTenantEntityExportRateLimit, "entity version creation", true), + ENTITY_IMPORT(DefaultTenantProfileConfiguration::getTenantEntityImportRateLimit, "entity version load", true), + NOTIFICATION_REQUESTS(DefaultTenantProfileConfiguration::getTenantNotificationRequestsRateLimit, "notification requests", true), + NOTIFICATION_REQUESTS_PER_RULE(DefaultTenantProfileConfiguration::getTenantNotificationRequestsPerRuleRateLimit, "notification requests per rule", false), + REST_REQUESTS_PER_TENANT(DefaultTenantProfileConfiguration::getTenantServerRestLimitsConfiguration, "REST API requests", true), + REST_REQUESTS_PER_CUSTOMER(DefaultTenantProfileConfiguration::getCustomerServerRestLimitsConfiguration, "REST API requests per customer", false), + WS_UPDATES_PER_SESSION(DefaultTenantProfileConfiguration::getWsUpdatesPerSessionRateLimit, "WS updates per session", true), + CASSANDRA_QUERIES(DefaultTenantProfileConfiguration::getCassandraQueryTenantRateLimitsConfiguration, "Cassandra queries", true), + PASSWORD_RESET(false, true), + TWO_FA_VERIFICATION_CODE_SEND(false, true), + TWO_FA_VERIFICATION_CODE_CHECK(false, true), + TRANSPORT_MESSAGES_PER_TENANT("transport messages", true), + TRANSPORT_MESSAGES_PER_DEVICE("transport messages per device", false); + + private Function configExtractor; + @Getter + private final boolean perTenant; + @Getter + private boolean refillRateLimitIntervally; + @Getter + private String label; + + LimitedApi(Function configExtractor, String label, boolean perTenant) { + this.configExtractor = configExtractor; + this.label = label; + this.perTenant = perTenant; + } + + LimitedApi(boolean perTenant, boolean refillRateLimitIntervally) { + this.perTenant = perTenant; + this.refillRateLimitIntervally = refillRateLimitIntervally; + } + + LimitedApi(String label, boolean perTenant) { + this.label = label; + this.perTenant = perTenant; + } + + public String getLimitConfig(DefaultTenantProfileConfiguration profileConfiguration) { + return Optional.ofNullable(configExtractor) + .map(extractor -> extractor.apply(profileConfiguration)) + .orElse(null); + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java index de07d03c67..251fae2ac0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java @@ -27,6 +27,7 @@ public enum NotificationType { NEW_PLATFORM_VERSION, ENTITIES_LIMIT, API_USAGE_LIMIT, - RULE_NODE + RULE_NODE, + RATE_LIMITS } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RateLimitsNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RateLimitsNotificationInfo.java new file mode 100644 index 0000000000..57fc278cff --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/RateLimitsNotificationInfo.java @@ -0,0 +1,59 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.notification.info; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.limit.LimitedApi; + +import java.util.Map; + +import static org.thingsboard.server.common.data.util.CollectionsUtil.mapOf; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class RateLimitsNotificationInfo implements RuleOriginatedNotificationInfo { + + private TenantId tenantId; + private String tenantName; + private LimitedApi api; + private EntityId limitLevel; + private String limitLevelEntityName; + + @Override + public Map getTemplateData() { + return mapOf( + "api", api.getLabel(), + "limitLevelEntityType", limitLevel != null ? limitLevel.getEntityType().getNormalName() : null, + "limitLevelEntityId", limitLevel != null ? limitLevel.getId().toString() : null, + "limitLevelEntityName", limitLevelEntityName, + "tenantName", tenantName, + "tenantId", tenantId.toString() + ); + } + + @Override + public TenantId getAffectedTenantId() { + return tenantId; + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java index b0eec28858..72028a616a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java @@ -35,6 +35,7 @@ import java.io.Serializable; @Type(value = NewPlatformVersionNotificationRuleTriggerConfig.class, name = "NEW_PLATFORM_VERSION"), @Type(value = EntitiesLimitNotificationRuleTriggerConfig.class, name = "ENTITIES_LIMIT"), @Type(value = ApiUsageLimitNotificationRuleTriggerConfig.class, name = "API_USAGE_LIMIT"), + @Type(value = RateLimitsNotificationRuleTriggerConfig.class, name = "RATE_LIMITS"), }) public interface NotificationRuleTriggerConfig extends Serializable { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java index dff86f4ba1..b591fe0245 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java @@ -28,7 +28,8 @@ public enum NotificationRuleTriggerType { RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, NEW_PLATFORM_VERSION(false), ENTITIES_LIMIT(false), - API_USAGE_LIMIT(false); + API_USAGE_LIMIT(false), + RATE_LIMITS(false); private final boolean tenantLevel; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsNotificationRuleTriggerConfig.java new file mode 100644 index 0000000000..f5ea83c47d --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsNotificationRuleTriggerConfig.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.notification.rule.trigger; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.thingsboard.server.common.data.limit.LimitedApi; + +import java.util.Set; +import java.util.stream.Collectors; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class RateLimitsNotificationRuleTriggerConfig implements NotificationRuleTriggerConfig { + + private Set apis; + + @Override + public NotificationRuleTriggerType getTriggerType() { + return NotificationRuleTriggerType.RATE_LIMITS; + } + + @Override + public String getDeduplicationKey() { + return apis == null ? "#" : apis.stream().sorted().map(Enum::name).collect(Collectors.joining(",")); + } + +} diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RateLimitsTrigger.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RateLimitsTrigger.java new file mode 100644 index 0000000000..afb06bb8d1 --- /dev/null +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RateLimitsTrigger.java @@ -0,0 +1,62 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.msg.notification.trigger; + +import lombok.Builder; +import lombok.Data; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.limit.LimitedApi; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; + +import java.util.concurrent.TimeUnit; + +@Data +@Builder +public class RateLimitsTrigger implements NotificationRuleTrigger { + + private final TenantId tenantId; + private final LimitedApi api; + private final EntityId limitLevel; + private final String limitLevelEntityName; + + @Override + public NotificationRuleTriggerType getType() { + return NotificationRuleTriggerType.RATE_LIMITS; + } + + @Override + public EntityId getOriginatorEntityId() { + return limitLevel != null ? limitLevel : tenantId; + } + + + @Override + public boolean deduplicate() { + return true; + } + + @Override + public String getDeduplicationKey() { + return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), api.toString()); + } + + @Override + public long getDefaultDeduplicationDuration() { + return TimeUnit.HOURS.toMillis(4); + } + +} diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTransportQueueFactory.java index c1ae9fe855..fa16ee9093 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTransportQueueFactory.java @@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg; @@ -110,6 +111,11 @@ public class AwsSqsTransportQueueFactory implements TbTransportQueueFactory { return new TbAwsSqsProducerTemplate<>(coreAdmin, sqsSettings, coreSettings.getTopic()); } + @Override + public TbQueueProducer> createTbCoreNotificationsMsgProducer() { + return new TbAwsSqsProducerTemplate<>(notificationAdmin, sqsSettings, coreSettings.getTopic()); + } + @Override public TbQueueConsumer> createTransportNotificationsConsumer() { return new TbAwsSqsConsumerTemplate<>(notificationAdmin, sqsSettings, transportNotificationSettings.getNotificationsTopic() + "_" + serviceInfoProvider.getServiceId(), diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryTbTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryTbTransportQueueFactory.java index 60c464ecab..6b6253acc4 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryTbTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryTbTransportQueueFactory.java @@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg; @@ -100,6 +101,11 @@ public class InMemoryTbTransportQueueFactory implements TbTransportQueueFactory return new InMemoryTbQueueProducer<>(storage, coreSettings.getTopic()); } + @Override + public TbQueueProducer> createTbCoreNotificationsMsgProducer() { + return new InMemoryTbQueueProducer<>(storage, coreSettings.getTopic()); + } + @Override public TbQueueConsumer> createTransportNotificationsConsumer() { return new InMemoryTbQueueConsumer<>(storage, transportNotificationSettings.getNotificationsTopic() + "." + serviceInfoProvider.getServiceId()); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java index 51e3dc99c7..300e0a44b6 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java @@ -18,7 +18,9 @@ package org.thingsboard.server.queue.provider; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; @@ -134,6 +136,16 @@ public class KafkaTbTransportQueueFactory implements TbTransportQueueFactory { return requestBuilder.build(); } + @Override + public TbQueueProducer> createTbCoreNotificationsMsgProducer() { + TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder> requestBuilder = TbKafkaProducerTemplate.builder(); + requestBuilder.settings(kafkaSettings); + requestBuilder.clientId("transport-node-to-core-notifications-" + serviceInfoProvider.getServiceId()); + requestBuilder.defaultTopic(coreSettings.getTopic()); + requestBuilder.admin(notificationAdmin); + return requestBuilder.build(); + } + @Override public TbQueueConsumer> createTransportNotificationsConsumer() { TbKafkaConsumerTemplate.TbKafkaConsumerTemplateBuilder> responseBuilder = TbKafkaConsumerTemplate.builder(); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTransportQueueFactory.java index d5665e2fbe..5cafaa4c48 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTransportQueueFactory.java @@ -18,7 +18,9 @@ package org.thingsboard.server.queue.provider; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; @@ -108,6 +110,11 @@ public class PubSubTransportQueueFactory implements TbTransportQueueFactory { return new TbPubSubProducerTemplate<>(coreAdmin, pubSubSettings, coreSettings.getTopic()); } + @Override + public TbQueueProducer> createTbCoreNotificationsMsgProducer() { + return new TbPubSubProducerTemplate<>(notificationAdmin, pubSubSettings, coreSettings.getTopic()); + } + @Override public TbQueueConsumer> createTransportNotificationsConsumer() { return new TbPubSubConsumerTemplate<>(notificationAdmin, pubSubSettings, diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTransportQueueFactory.java index f11a877fc5..bcbd60a14e 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTransportQueueFactory.java @@ -18,7 +18,9 @@ package org.thingsboard.server.queue.provider; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; @@ -110,6 +112,11 @@ public class RabbitMqTransportQueueFactory implements TbTransportQueueFactory { return new TbRabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getTopic()); } + @Override + public TbQueueProducer> createTbCoreNotificationsMsgProducer() { + return new TbRabbitMqProducerTemplate<>(notificationAdmin, rabbitMqSettings, coreSettings.getTopic()); + } + @Override public TbQueueConsumer> createTransportNotificationsConsumer() { return new TbRabbitMqConsumerTemplate<>(notificationAdmin, rabbitMqSettings, transportNotificationSettings.getNotificationsTopic() + "." + serviceInfoProvider.getServiceId(), diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTransportQueueFactory.java index 15e661f5b0..0a4bb59663 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTransportQueueFactory.java @@ -18,7 +18,9 @@ package org.thingsboard.server.queue.provider; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; +import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceMsg; @@ -110,6 +112,11 @@ public class ServiceBusTransportQueueFactory implements TbTransportQueueFactory return new TbServiceBusProducerTemplate<>(coreAdmin, serviceBusSettings, coreSettings.getTopic()); } + @Override + public TbQueueProducer> createTbCoreNotificationsMsgProducer() { + return new TbServiceBusProducerTemplate<>(notificationAdmin, serviceBusSettings, coreSettings.getTopic()); + } + @Override public TbQueueConsumer> createTransportNotificationsConsumer() { return new TbServiceBusConsumerTemplate<>(notificationAdmin, serviceBusSettings, diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueFactory.java index feff3830fc..c7d2f78838 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueFactory.java @@ -16,6 +16,7 @@ package org.thingsboard.server.queue.provider; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; +import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.TransportApiRequestMsg; @@ -33,6 +34,8 @@ public interface TbTransportQueueFactory extends TbUsageStatsClientQueueFactory TbQueueProducer> createTbCoreMsgProducer(); + TbQueueProducer> createTbCoreNotificationsMsgProducer(); + TbQueueConsumer> createTransportNotificationsConsumer(); } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProducerProvider.java index e9177d8b1c..afbcd718a5 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProducerProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProducerProvider.java @@ -36,6 +36,7 @@ public class TbTransportQueueProducerProvider implements TbQueueProducerProvider private final TbTransportQueueFactory tbQueueProvider; private TbQueueProducer> toRuleEngine; private TbQueueProducer> toTbCore; + private TbQueueProducer> toTbCoreNotifications; private TbQueueProducer> toUsageStats; public TbTransportQueueProducerProvider(TbTransportQueueFactory tbQueueProvider) { @@ -47,6 +48,7 @@ public class TbTransportQueueProducerProvider implements TbQueueProducerProvider this.toTbCore = tbQueueProvider.createTbCoreMsgProducer(); this.toRuleEngine = tbQueueProvider.createRuleEngineMsgProducer(); this.toUsageStats = tbQueueProvider.createToUsageStatsServiceMsgProducer(); + this.toTbCoreNotifications = tbQueueProvider.createTbCoreNotificationsMsgProducer(); } @Override @@ -71,7 +73,7 @@ public class TbTransportQueueProducerProvider implements TbQueueProducerProvider @Override public TbQueueProducer> getTbCoreNotificationsMsgProducer() { - throw new RuntimeException("Not Implemented! Should not be used by Transport!"); + return toTbCoreNotifications; } @Override diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java index 6539f2d22c..47f7717212 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java @@ -78,11 +78,11 @@ public class DefaultTransportRateLimitService implements TransportRateLimitServi return null; } - private boolean checkEntityRateLimit(int dataPoints, EntityTransportRateLimits tenantLimits) { + private boolean checkEntityRateLimit(int dataPoints, EntityTransportRateLimits limits) { if (dataPoints > 0) { - return tenantLimits.getTelemetryMsgRateLimit().tryConsume() && tenantLimits.getTelemetryDataPointsRateLimit().tryConsume(dataPoints); + return limits.getTelemetryMsgRateLimit().tryConsume() && limits.getTelemetryDataPointsRateLimit().tryConsume(dataPoints); } else { - return tenantLimits.getRegularMsgRateLimit().tryConsume(); + return limits.getRegularMsgRateLimit().tryConsume(); } } @@ -241,7 +241,7 @@ public class DefaultTransportRateLimitService implements TransportRateLimitServi } else { TransportRateLimit regularMsgRateLimit = newLimit(tenant ? profile.getTransportTenantMsgRateLimit() : profile.getTransportDeviceMsgRateLimit()); TransportRateLimit telemetryMsgRateLimit = newLimit(tenant ? profile.getTransportTenantTelemetryMsgRateLimit() : profile.getTransportDeviceTelemetryMsgRateLimit()); - TransportRateLimit telemetryDpRateLimit = newLimit(tenant ? profile.getTransportTenantTelemetryDataPointsRateLimit() : profile.getTransportTenantTelemetryDataPointsRateLimit()); + TransportRateLimit telemetryDpRateLimit = newLimit(tenant ? profile.getTransportTenantTelemetryDataPointsRateLimit() : profile.getTransportDeviceTelemetryDataPointsRateLimit()); return new EntityTransportRateLimits(regularMsgRateLimit, telemetryMsgRateLimit, telemetryDpRateLimit); } } @@ -251,21 +251,16 @@ public class DefaultTransportRateLimitService implements TransportRateLimitServi } private EntityTransportRateLimits getTenantRateLimits(TenantId tenantId) { - EntityTransportRateLimits limits = perTenantLimits.get(tenantId); - if (limits == null) { - limits = createRateLimits(tenantProfileCache.get(tenantId), true); - perTenantLimits.put(tenantId, limits); - } - return limits; + return perTenantLimits.computeIfAbsent(tenantId, k -> { + return createRateLimits(tenantProfileCache.get(tenantId), true); + }); } private EntityTransportRateLimits getDeviceRateLimits(TenantId tenantId, DeviceId deviceId) { - EntityTransportRateLimits limits = perDeviceLimits.get(deviceId); - if (limits == null) { - limits = createRateLimits(tenantProfileCache.get(tenantId), false); - perDeviceLimits.put(deviceId, limits); + return perDeviceLimits.computeIfAbsent(deviceId, k -> { + EntityTransportRateLimits limits = createRateLimits(tenantProfileCache.get(tenantId), false); tenantDevices.computeIfAbsent(tenantId, id -> ConcurrentHashMap.newKeySet()).add(deviceId); - } - return limits; + return limits; + }); } } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index b495448d90..69e4de7b74 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -48,9 +48,12 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.trigger.RateLimitsTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.session.SessionMsgType; @@ -177,6 +180,7 @@ public class DefaultTransportService implements TransportService { private final SchedulerComponent scheduler; private final ApplicationEventPublisher eventPublisher; private final TransportResourceCache transportResourceCache; + private final NotificationRuleProcessor notificationRuleProcessor; protected TbQueueRequestTemplate, TbProtoQueueMsg> transportApiRequestTemplate; protected TbQueueProducer> ruleEngineMsgProducer; @@ -206,7 +210,7 @@ public class DefaultTransportService implements TransportService { TransportTenantProfileCache tenantProfileCache, TransportRateLimitService rateLimitService, DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler, TransportResourceCache transportResourceCache, - ApplicationEventPublisher eventPublisher) { + ApplicationEventPublisher eventPublisher, NotificationRuleProcessor notificationRuleProcessor) { this.partitionService = partitionService; this.serviceInfoProvider = serviceInfoProvider; this.queueProvider = queueProvider; @@ -220,6 +224,7 @@ public class DefaultTransportService implements TransportService { this.scheduler = scheduler; this.transportResourceCache = transportResourceCache; this.eventPublisher = eventPublisher; + this.notificationRuleProcessor = notificationRuleProcessor; } @PostConstruct @@ -877,6 +882,14 @@ public class DefaultTransportService implements TransportService { if (callback != null) { callback.onError(new TbRateLimitsException(rateLimitedEntityType)); } + if (rateLimitedEntityType == EntityType.DEVICE || rateLimitedEntityType == EntityType.TENANT) { + notificationRuleProcessor.process(RateLimitsTrigger.builder() + .tenantId(tenantId) + .api(rateLimitedEntityType == EntityType.DEVICE ? LimitedApi.TRANSPORT_MESSAGES_PER_DEVICE : LimitedApi.TRANSPORT_MESSAGES_PER_TENANT) + .limitLevel(rateLimitedEntityType == EntityType.DEVICE ? deviceId : tenantId) + .limitLevelEntityName(rateLimitedEntityType == EntityType.DEVICE ? sessionInfo.getDeviceName() : null) + .build()); + } return false; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java index 0e25a0cab3..4262decfed 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java @@ -25,6 +25,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.settings.NotificationSettings; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.platform.AffectedTenantAdministratorsFilter; @@ -35,9 +36,12 @@ import org.thingsboard.server.common.data.notification.targets.platform.Platform import org.thingsboard.server.common.data.notification.targets.platform.SystemAdministratorsFilter; import org.thingsboard.server.common.data.notification.targets.platform.TenantAdministratorsFilter; import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter; +import org.thingsboard.server.common.data.notification.targets.platform.UsersFilterType; +import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.settings.AdminSettingsService; import java.util.Collections; +import java.util.List; import java.util.Optional; @Service @@ -46,6 +50,7 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS private final AdminSettingsService adminSettingsService; private final NotificationTargetService notificationTargetService; + private final NotificationTemplateService notificationTemplateService; private final DefaultNotifications defaultNotifications; private static final String SETTINGS_KEY = "notifications"; @@ -98,6 +103,10 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS defaultNotifications.create(tenantId, DefaultNotifications.apiFeatureDisabledForSysadmin, sysAdmins.getId()); defaultNotifications.create(tenantId, DefaultNotifications.apiFeatureDisabledForTenant, affectedTenantAdmins.getId()); + defaultNotifications.create(tenantId, DefaultNotifications.exceededRateLimits, affectedTenantAdmins.getId()); + defaultNotifications.create(tenantId, DefaultNotifications.exceededPerEntityRateLimits, affectedTenantAdmins.getId()); + defaultNotifications.create(tenantId, DefaultNotifications.exceededRateLimitsForSysadmin, sysAdmins.getId()); + defaultNotifications.create(tenantId, DefaultNotifications.newPlatformVersion, sysAdmins.getId()); return; } @@ -116,6 +125,29 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS defaultNotifications.create(tenantId, DefaultNotifications.ruleEngineComponentLifecycleFailure, tenantAdmins.getId()); } + @Override + public void updateDefaultNotificationConfigs(TenantId tenantId) { + if (tenantId.isSysTenantId()) { + if (notificationTemplateService.findNotificationTemplatesByTenantIdAndNotificationTypes(tenantId, + List.of(NotificationType.RATE_LIMITS), new PageLink(1)).getTotalElements() > 0) { + return; + } + + NotificationTarget sysAdmins = notificationTargetService.findNotificationTargetsByTenantIdAndUsersFilterType(tenantId, UsersFilterType.SYSTEM_ADMINISTRATORS).stream() + .findFirst().orElseGet(() -> { + return createTarget(tenantId, "System administrators", new SystemAdministratorsFilter(), "All system administrators"); + }); + NotificationTarget affectedTenantAdmins = notificationTargetService.findNotificationTargetsByTenantIdAndUsersFilterType(tenantId, UsersFilterType.AFFECTED_TENANT_ADMINISTRATORS).stream() + .findFirst().orElseGet(() -> { + return createTarget(tenantId, "Affected tenant's administrators", new AffectedTenantAdministratorsFilter(), ""); + }); + + defaultNotifications.create(tenantId, DefaultNotifications.exceededRateLimits, affectedTenantAdmins.getId()); + defaultNotifications.create(tenantId, DefaultNotifications.exceededPerEntityRateLimits, affectedTenantAdmins.getId()); + defaultNotifications.create(tenantId, DefaultNotifications.exceededRateLimitsForSysadmin, sysAdmins.getId()); + } + } + private NotificationTarget createTarget(TenantId tenantId, String name, UsersFilter filter, String description) { NotificationTarget target = new NotificationTarget(); target.setTenantId(tenantId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTargetService.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTargetService.java index 78d5a4b454..97a7ee0e27 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTargetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationTargetService.java @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.notification.targets.platform.Platform import org.thingsboard.server.common.data.notification.targets.platform.TenantAdministratorsFilter; import org.thingsboard.server.common.data.notification.targets.platform.UserListFilter; import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter; +import org.thingsboard.server.common.data.notification.targets.platform.UsersFilterType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.entity.AbstractEntityService; @@ -93,6 +94,11 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl return notificationTargetDao.findByTenantIdAndIds(tenantId, ids); } + @Override + public List findNotificationTargetsByTenantIdAndUsersFilterType(TenantId tenantId, UsersFilterType filterType) { + return notificationTargetDao.findByTenantIdAndUsersFilterType(tenantId, filterType); + } + @Override public PageData findRecipientsForNotificationTarget(TenantId tenantId, CustomerId customerId, NotificationTargetId targetId, PageLink pageLink) { NotificationTarget notificationTarget = findNotificationTargetById(tenantId, targetId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java index 01f9f68ae4..c8f458b40d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java @@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; import org.thingsboard.server.common.data.id.NotificationTargetId; import org.thingsboard.server.common.data.id.NotificationTemplateId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.rule.DefaultNotificationRuleRecipientsConfig; @@ -44,16 +45,20 @@ import org.thingsboard.server.common.data.notification.rule.trigger.EntityAction import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig; import org.thingsboard.server.common.data.notification.template.WebDeliveryMethodNotificationTemplate; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import static java.util.function.Predicate.not; import static org.thingsboard.common.util.JacksonUtil.newObjectNode; import static org.thingsboard.server.dao.DaoUtil.toUUIDs; @@ -66,6 +71,7 @@ public class DefaultNotifications { .subject("Infrastructure maintenance") .text("Maintenance work is scheduled for tomorrow (7:00 a.m. - 9:00 a.m. UTC)") .build(); + public static final DefaultNotification entitiesLimitForSysadmin = DefaultNotification.builder() .name("Entities count limit notification for sysadmin") .type(NotificationType.ENTITIES_LIMIT) @@ -88,6 +94,7 @@ public class DefaultNotifications { .description("Send notification to tenant admins when count of entities of some type reached 80% threshold of the limit") .build()) .build(); + public static final DefaultNotification apiFeatureWarningForSysadmin = DefaultNotification.builder() .name("API feature warning notification for sysadmin") .type(NotificationType.API_USAGE_LIMIT) @@ -134,6 +141,51 @@ public class DefaultNotifications { .description("Send notification to tenant admins when API feature is disabled") .build()) .build(); + + public static final DefaultNotification exceededRateLimits = DefaultNotification.builder() + .name("Exceeded per-tenant rate limits notification for tenant") + .type(NotificationType.RATE_LIMITS) + .subject("Rate limits exceeded") + .text("Rate limits for ${api} exceeded") + .icon("block").color("#e91a1a") + .rule(DefaultRule.builder() + .name("Per-tenant rate limits exceeded") + .triggerConfig(RateLimitsNotificationRuleTriggerConfig.builder() + .apis(Arrays.stream(LimitedApi.values()) + .filter(LimitedApi::isPerTenant) + .filter(api -> api.getLabel() != null) + .collect(Collectors.toSet())) + .build()) + .description("Send notification to tenant admins when some per-tenant rate limit is exceeded") + .build()) + .build(); + public static final DefaultNotification exceededPerEntityRateLimits = DefaultNotification.builder() + .name("Exceeded per-entity rate limits notification for tenant") + .type(NotificationType.RATE_LIMITS) + .subject("Rate limits exceeded") + .text("Rate limits for ${api} exceeded for '${limitLevelEntityName}'") + .icon("block").color("#e91a1a") + .rule(DefaultRule.builder() + .name("Per-entity rate limits exceeded") + .triggerConfig(RateLimitsNotificationRuleTriggerConfig.builder() + .apis(Arrays.stream(LimitedApi.values()) + .filter(not(LimitedApi::isPerTenant)) + .filter(api -> api.getLabel() != null) + .collect(Collectors.toSet())) + .build()) + .description("Send notification to tenant admins when some per-entity rate limit is exceeded for an entity") + .build()) + .build(); + public static final DefaultNotification exceededRateLimitsForSysadmin = exceededRateLimits.toBuilder() + .name("Exceeded per-tenant rate limits notification for sysadmin") + .subject("Rate limits exceeded for tenant ${tenantName}") + .button("Go to tenant").link("/tenants/${tenantId}") + .rule(exceededRateLimits.getRule().toBuilder() + .name("Per-tenant rate limits exceeded (sysadmin)") + .description("Send notification to system admins when a tenant exceeds some per-tenant rate limit") + .build()) + .build(); + public static final DefaultNotification newPlatformVersion = DefaultNotification.builder() .name("New platform version notification") .type(NotificationType.NEW_PLATFORM_VERSION) diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/NotificationTargetDao.java b/dao/src/main/java/org/thingsboard/server/dao/notification/NotificationTargetDao.java index 912e873bcc..3e542cc50f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/NotificationTargetDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/NotificationTargetDao.java @@ -19,6 +19,7 @@ import org.thingsboard.server.common.data.id.NotificationTargetId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; +import org.thingsboard.server.common.data.notification.targets.platform.UsersFilterType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.Dao; @@ -35,6 +36,8 @@ public interface NotificationTargetDao extends Dao, TenantEn List findByTenantIdAndIds(TenantId tenantId, List ids); + List findByTenantIdAndUsersFilterType(TenantId tenantId, UsersFilterType filterType); + void removeByTenantId(TenantId tenantId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTargetDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTargetDao.java index d976802fd2..64c679c845 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTargetDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTargetDao.java @@ -66,6 +66,12 @@ public class JpaNotificationTargetDao extends JpaAbstractDao findByTenantIdAndUsersFilterType(TenantId tenantId, UsersFilterType filterType) { + return DaoUtil.convertDataList(notificationTargetRepository.findByTenantIdAndSearchTextAndUsersFilterTypeIfPresent(tenantId.getId(), "", + List.of(filterType.name()), DaoUtil.toPageable(new PageLink(Integer.MAX_VALUE))).getContent()); + } + @Override public void removeByTenantId(TenantId tenantId) { notificationTargetRepository.deleteByTenantId(tenantId.getId()); diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java index 64b4eb3666..4c8d0c5afe 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java @@ -37,7 +37,7 @@ import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.common.stats.StatsType; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.nosql.CassandraStatementTask; -import org.thingsboard.server.dao.util.limits.LimitedApi; +import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import javax.annotation.Nullable; diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java b/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java index 918f16ef19..ede6855d5e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java @@ -20,11 +20,16 @@ import com.github.benmanes.caffeine.cache.Caffeine; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.exception.TenantProfileNotFoundException; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.limit.LimitedApi; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; +import org.thingsboard.server.common.msg.notification.trigger.RateLimitsTrigger; import org.thingsboard.server.common.msg.tools.TbRateLimits; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; @@ -35,11 +40,14 @@ import java.util.concurrent.TimeUnit; public class DefaultRateLimitService implements RateLimitService { private final TbTenantProfileCache tenantProfileCache; + private final NotificationRuleProcessor notificationRuleProcessor; public DefaultRateLimitService(TbTenantProfileCache tenantProfileCache, + @Lazy NotificationRuleProcessor notificationRuleProcessor, @Value("${cache.rateLimits.timeToLiveInMinutes:120}") int rateLimitsTtl, @Value("${cache.rateLimits.maxSize:200000}") int rateLimitsCacheMaxSize) { this.tenantProfileCache = tenantProfileCache; + this.notificationRuleProcessor = notificationRuleProcessor; this.rateLimits = Caffeine.newBuilder() .expireAfterAccess(rateLimitsTtl, TimeUnit.MINUTES) .maximumSize(rateLimitsCacheMaxSize) @@ -64,9 +72,17 @@ public class DefaultRateLimitService implements RateLimitService { } String rateLimitConfig = tenantProfile.getProfileConfiguration() - .map(profileConfiguration -> api.getLimitConfig(profileConfiguration, level)) - .orElse(null); - return checkRateLimit(api, level, rateLimitConfig); + .map(api::getLimitConfig).orElse(null); + boolean success = checkRateLimit(api, level, rateLimitConfig); + if (!success) { + notificationRuleProcessor.process(RateLimitsTrigger.builder() + .tenantId(tenantId) + .api(api) + .limitLevel(level instanceof EntityId ? (EntityId) level : tenantId) + .limitLevelEntityName(null) + .build()); + } + return success; } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/limits/LimitedApi.java b/dao/src/main/java/org/thingsboard/server/dao/util/limits/LimitedApi.java deleted file mode 100644 index ee79230d8a..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/util/limits/LimitedApi.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util.limits; - -import lombok.Getter; -import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; - -import java.util.function.BiFunction; -import java.util.function.Function; - -public enum LimitedApi { - - ENTITY_EXPORT(DefaultTenantProfileConfiguration::getTenantEntityExportRateLimit), - ENTITY_IMPORT(DefaultTenantProfileConfiguration::getTenantEntityImportRateLimit), - NOTIFICATION_REQUESTS(DefaultTenantProfileConfiguration::getTenantNotificationRequestsRateLimit), - NOTIFICATION_REQUESTS_PER_RULE(DefaultTenantProfileConfiguration::getTenantNotificationRequestsPerRuleRateLimit), - REST_REQUESTS((profileConfiguration, level) -> ((EntityId) level).getEntityType() == EntityType.TENANT ? - profileConfiguration.getTenantServerRestLimitsConfiguration() : - profileConfiguration.getCustomerServerRestLimitsConfiguration()), - WS_UPDATES_PER_SESSION(DefaultTenantProfileConfiguration::getWsUpdatesPerSessionRateLimit), - CASSANDRA_QUERIES(DefaultTenantProfileConfiguration::getCassandraQueryTenantRateLimitsConfiguration), - PASSWORD_RESET(true), - TWO_FA_VERIFICATION_CODE_SEND(true), - TWO_FA_VERIFICATION_CODE_CHECK(true); - - private final BiFunction configExtractor; - @Getter - private final boolean refillRateLimitIntervally; - - LimitedApi(Function configExtractor) { - this((profileConfiguration, level) -> configExtractor.apply(profileConfiguration)); - } - - LimitedApi(BiFunction configExtractor) { - this.configExtractor = configExtractor; - this.refillRateLimitIntervally = false; - } - - LimitedApi(boolean refillRateLimitIntervally) { - this.configExtractor = null; - this.refillRateLimitIntervally = refillRateLimitIntervally; - } - - public String getLimitConfig(DefaultTenantProfileConfiguration profileConfiguration, Object level) { - if (configExtractor != null) { - return configExtractor.apply(profileConfiguration, level); - } else { - throw new IllegalArgumentException("No tenant profile config for " + name() + " rate limits"); - } - } - -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/limits/RateLimitService.java b/dao/src/main/java/org/thingsboard/server/dao/util/limits/RateLimitService.java index c3f2fd179f..1f6e87111c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/limits/RateLimitService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/limits/RateLimitService.java @@ -16,6 +16,7 @@ package org.thingsboard.server.dao.util.limits; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.limit.LimitedApi; public interface RateLimitService { diff --git a/msa/vc-executor/src/main/resources/tb-vc-executor.yml b/msa/vc-executor/src/main/resources/tb-vc-executor.yml index 9d5ad35388..75f9e09d3c 100644 --- a/msa/vc-executor/src/main/resources/tb-vc-executor.yml +++ b/msa/vc-executor/src/main/resources/tb-vc-executor.yml @@ -203,3 +203,10 @@ service: type: "${TB_SERVICE_TYPE:tb-vc-executor}" # Unique id for this service (autogenerated if empty) id: "${TB_SERVICE_ID:}" + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 7ea553fe5c..8fe079859a 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -302,3 +302,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index 346ec48eae..f05db08643 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -287,3 +287,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 4e8167d89d..745a7d126a 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -369,3 +369,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index 1e0b1ebcd4..3795c533a7 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -317,3 +317,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index 9f086bcbc5..11dcc96010 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -267,3 +267,10 @@ management: exposure: # Expose metrics endpoint (use value 'prometheus' to enable prometheus metrics). include: '${METRICS_ENDPOINTS_EXPOSE:info}' + +notification_system: + rules: + trigger_types_configs: + RATE_LIMITS: + # In milliseconds, 4 hours by default + deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" From d5d087d82616670d549bf48aee02befc6a0d905d Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 2 Jun 2023 15:09:35 +0300 Subject: [PATCH 118/207] UI part and help page for exceeded rate limits notification rule --- .../rule-notification-dialog.component.html | 12 +++++ .../rule-notification-dialog.component.ts | 11 +++- .../template-notification-dialog.component.ts | 1 + .../app/shared/models/notification.models.ts | 13 ++++- .../help/en_US/notification/rate_limits.md | 50 +++++++++++++++++++ .../assets/locale/locale.constant-en_US.json | 5 +- 6 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 ui-ngx/src/assets/help/en_US/notification/rate_limits.md diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html index fc48392e8c..0cf94e0292 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html @@ -496,6 +496,18 @@ + + {{ 'notification.rate-limits-trigger-settings' | translate }} +
+
+ + notification.description + + +
+
+
diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts index 93b22911f3..985f121432 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts @@ -95,6 +95,7 @@ export class RuleNotificationDialogComponent extends entitiesLimitTemplateForm: FormGroup; apiUsageLimitTemplateForm: FormGroup; newPlatformVersionTemplateForm: FormGroup; + rateLimitsTemplateForm: FormGroup; triggerType = TriggerType; triggerTypes: TriggerType[]; @@ -302,6 +303,12 @@ export class RuleNotificationDialogComponent extends }) }); + this.rateLimitsTemplateForm = this.fb.group({ + triggerConfig: this.fb.group({ + + }) + }); + this.triggerTypeFormsMap = new Map([ [TriggerType.ALARM, this.alarmTemplateForm], [TriggerType.ALARM_COMMENT, this.alarmCommentTemplateForm], @@ -311,7 +318,8 @@ export class RuleNotificationDialogComponent extends [TriggerType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, this.ruleEngineEventsTemplateForm], [TriggerType.ENTITIES_LIMIT, this.entitiesLimitTemplateForm], [TriggerType.API_USAGE_LIMIT, this.apiUsageLimitTemplateForm], - [TriggerType.NEW_PLATFORM_VERSION, this.newPlatformVersionTemplateForm] + [TriggerType.NEW_PLATFORM_VERSION, this.newPlatformVersionTemplateForm], + [TriggerType.RATE_LIMITS, this.rateLimitsTemplateForm] ]); if (data.isAdd || data.isCopy) { @@ -447,6 +455,7 @@ export class RuleNotificationDialogComponent extends TriggerType.ENTITIES_LIMIT, TriggerType.API_USAGE_LIMIT, TriggerType.NEW_PLATFORM_VERSION, + TriggerType.RATE_LIMITS ]); if (this.isSysAdmin()) { diff --git a/ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.ts index b4ba480732..983ad4b569 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/template/template-notification-dialog.component.ts @@ -181,6 +181,7 @@ export class TemplateNotificationDialogComponent NotificationType.ENTITIES_LIMIT, NotificationType.API_USAGE_LIMIT, NotificationType.NEW_PLATFORM_VERSION, + NotificationType.RATE_LIMITS ]); if (this.isSysAdmin()) { diff --git a/ui-ngx/src/app/shared/models/notification.models.ts b/ui-ngx/src/app/shared/models/notification.models.ts index 59af9295e1..48902231ca 100644 --- a/ui-ngx/src/app/shared/models/notification.models.ts +++ b/ui-ngx/src/app/shared/models/notification.models.ts @@ -444,7 +444,8 @@ export enum NotificationType { ENTITIES_LIMIT = 'ENTITIES_LIMIT', API_USAGE_LIMIT = 'API_USAGE_LIMIT', NEW_PLATFORM_VERSION = 'NEW_PLATFORM_VERSION', - RULE_NODE = 'RULE_NODE' + RULE_NODE = 'RULE_NODE', + RATE_LIMITS = 'RATE_LIMITS' } export const NotificationTypeIcons = new Map([ @@ -549,6 +550,12 @@ export const NotificationTemplateTypeTranslateMap = new Map([ @@ -574,4 +582,5 @@ export const TriggerTypeTranslationMap = new Map([ [TriggerType.ENTITIES_LIMIT, 'notification.trigger.entities-limit'], [TriggerType.API_USAGE_LIMIT, 'notification.trigger.api-usage-limit'], [TriggerType.NEW_PLATFORM_VERSION, 'notification.trigger.new-platform-version'], + [TriggerType.RATE_LIMITS, 'notification.trigger.rate-limits'], ]); diff --git a/ui-ngx/src/assets/help/en_US/notification/rate_limits.md b/ui-ngx/src/assets/help/en_US/notification/rate_limits.md new file mode 100644 index 0000000000..8f6319ad80 --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/notification/rate_limits.md @@ -0,0 +1,50 @@ +#### Exceeded rate limits notification templatization + +
+
+ +Notification subject and message fields support templatization. +The list of available templatization parameters depends on the template type. +See the available types and parameters below: + +Available template parameters: + +* `api` - rate-limited API label; one of: 'REST API requests', 'REST API requests per customer', 'transport messages', + 'transport messages per device', 'Cassandra queries', 'WS updates per session', 'notification requests', 'notification requests per rule', + 'entity version creation', 'entity version load'; +* `limitLevelEntityType` - entity type of the limit level entity, e.g. 'Tenant', 'Device', 'Notification rule', 'Customer', etc.; +* `limitLevelEntityId` - id of the limit level entity; +* `limitLevelEntityName` - name of the limit level entity; +* `tenantId` - id of the tenant; +* `tenantName` - name of the tenant; +* `recipientTitle` - title of the recipient (first and last name if specified, email otherwise); +* `recipientEmail` - email of the recipient; +* `recipientFirstName` - first name of the recipient; +* `recipientLastName` - last name of the recipient; + +Parameter names must be wrapped using `${...}`. For example: `${recipientFirstName}`. +You may also modify the value of the parameter with one of the suffixes: + +* `upperCase`, for example - `${recipientFirstName:upperCase}` +* `lowerCase`, for example - `${recipientFirstName:lowerCase}` +* `capitalize`, for example - `${recipientFirstName:capitalize}` + +
+ +##### Examples + +Let's assume customer 'Customer A' exceeded rate limit for per-customer REST API requests. The following template: + +```text +Rate limits for ${api} exceeded for ${limitLevelEntityType:lowerCase} '${limitLevelEntityName}' +{:copy-code} +``` + +will be transformed to: + +```text +Rate limits for REST API requests per customer exceeded for customer 'Customer A' +``` + +
+
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 2fab5b1e85..1c20dbe740 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2818,6 +2818,7 @@ "api-feature-hint": "If the field is empty, the trigger will be applied to all api features", "api-usage-trigger-settings": "API usage trigger settings", "new-platform-version-trigger-settings": "New platform version trigger settings", + "rate-limits-trigger-settings": "Exceeded rate limits trigger settings", "at-least-one-should-be-selected": "At least one should be selected", "basic-settings": "Basic settings", "button-text": "Button text", @@ -3013,7 +3014,8 @@ "general": "General", "rule-engine-lifecycle-event": "Rule engine lifecycle event", "rule-node": "Rule node", - "new-platform-version": "New platform version" + "new-platform-version": "New platform version", + "rate-limits": "Exceeded rate limits" }, "templates": "Templates", "notification-templates": "Notifications / Templates", @@ -3032,6 +3034,7 @@ "entity-action": "Entity action", "rule-engine-lifecycle-event": "Rule engine lifecycle event", "new-platform-version": "New platform version", + "rate-limits": "Exceeded rate limits", "trigger": "Trigger", "trigger-required": "Trigger is required" }, From b1211f2bd56183ec518c0f7a8d770ab0500c81fd Mon Sep 17 00:00:00 2001 From: Seraphym-Tuhai Date: Fri, 2 Jun 2023 15:43:19 +0300 Subject: [PATCH 119/207] small refactoring --- .../msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java index 3d9ec2b278..df14547bda 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ui/tests/devicessmoke/MakeDevicePrivateTest.java @@ -16,7 +16,7 @@ package org.thingsboard.server.msa.ui.tests.devicessmoke; import io.qameta.allure.Description; -import io.qameta.allure.Epic; +import io.qameta.allure.Feature; import org.openqa.selenium.WebElement; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeMethod; @@ -29,7 +29,7 @@ import static org.thingsboard.server.msa.ui.base.AbstractBasePage.random; import static org.thingsboard.server.msa.ui.utils.Const.ENTITY_NAME; import static org.thingsboard.server.msa.ui.utils.Const.PUBLIC_CUSTOMER_NAME; -@Epic("Make device private") +@Feature("Make device private") public class MakeDevicePrivateTest extends AbstractDeviceTest { private CustomerPageHelper customerPage; From f2684e124d7afd5f5a3d7f106980d8c18cbfcd07 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 2 Jun 2023 18:20:15 +0300 Subject: [PATCH 120/207] Fix AlarmCommentControllerTest --- .../controller/AbstractNotifyEntityTest.java | 20 ++++++++-------- .../AlarmCommentControllerTest.java | 23 +++++++++++-------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index 6c42c7604d..d5eabdff2a 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -264,7 +264,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { int cntTime = 1; testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); - tesPushMsgToCoreTime(cntTime); + testPushMsgToCoreTime(cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -363,13 +363,13 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.any(entityId.getClass()), Mockito.any(ComponentLifecycleEvent.class)); } - private void tesPushMsgToCoreTime(int cntTime) { + private void testPushMsgToCoreTime(int cntTime) { Mockito.verify(tbClusterService, times(cntTime)).pushMsgToCore(Mockito.any(ToDeviceActorNotificationMsg.class), Mockito.isNull()); } protected void testLogEntityAction(HasName entity, EntityId originatorId, TenantId tenantId, - CustomerId customerId, UserId userId, String userName, - ActionType actionType, int cntTime, Object... additionalInfo) { + CustomerId customerId, UserId userId, String userName, + ActionType actionType, int cntTime, Object... additionalInfo) { ArgumentMatcher matcherEntityEquals = entity == null ? Objects::isNull : argument -> argument.toString().equals(entity.toString()); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); ArgumentMatcher matcherCustomerId = customerId == null ? @@ -380,10 +380,10 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { actionType, cntTime, extractMatcherAdditionalInfo(additionalInfo)); } - private void testLogEntityActionEntityEqClass(HasName entity, EntityId originatorId, TenantId tenantId, - CustomerId customerId, UserId userId, String userName, - ActionType actionType, int cntTime, Object... additionalInfo) { - ArgumentMatcher matcherEntityEquals = argument -> argument.getClass().equals(entity.getClass()); + protected void testLogEntityActionEntityEqClass(HasName entity, EntityId originatorId, TenantId tenantId, + CustomerId customerId, UserId userId, String userName, + ActionType actionType, int cntTime, Object... additionalInfo) { + ArgumentMatcher matcherEntityEquals = argument -> entity.getClass().isAssignableFrom(argument.getClass()); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); ArgumentMatcher matcherCustomerId = customerId == null ? argument -> argument.getClass().equals(CustomerId.class) : argument -> argument.equals(customerId); @@ -600,8 +600,8 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { return fieldName + " length must be equal or less than 255"; } - protected String msgErrorNoFound(String entityClassName, String assetIdStr) { - return entityClassName + " with id [" + assetIdStr + "] is not found"; + protected String msgErrorNoFound(String entityClassName, String entityIdStr) { + return entityClassName + " with id [" + entityIdStr + "] is not found"; } private String entityClassToEntityTypeName(HasName entity) { diff --git a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java index 287ae7cfe1..bf3e7528c9 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java @@ -46,6 +46,7 @@ import java.util.LinkedList; import java.util.List; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j @@ -104,7 +105,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { AlarmComment createdComment = createAlarmComment(alarm.getId()); - testLogEntityAction(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED_COMMENT, 1, createdComment); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED_COMMENT, 1, createdComment); } @Test @@ -116,7 +117,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { AlarmComment createdComment = createAlarmComment(alarm.getId()); Assert.assertEquals(AlarmCommentType.OTHER, createdComment.getType()); - testLogEntityAction(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED_COMMENT, 1, createdComment); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED_COMMENT, 1, createdComment); } @Test @@ -135,7 +136,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { Assert.assertEquals("true", updatedAlarmComment.getComment().get("edited").asText()); Assert.assertNotNull(updatedAlarmComment.getComment().get("editedOn")); - testLogEntityAction(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.UPDATED_COMMENT, 1, savedComment); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.UPDATED_COMMENT, 1, savedComment); } @Test @@ -154,7 +155,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { Assert.assertEquals("true", updatedAlarmComment.getComment().get("edited").asText()); Assert.assertNotNull(updatedAlarmComment.getComment().get("editedOn")); - testLogEntityAction(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.UPDATED_COMMENT, 1, updatedAlarmComment); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.UPDATED_COMMENT, 1, updatedAlarmComment); } @Test @@ -169,8 +170,8 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { savedComment.setComment(newComment); doPost("/api/alarm/" + alarm.getId() + "/comment", savedComment) - .andExpect(status().isForbidden()) - .andExpect(statusReason(containsString(msgErrorPermission))); + .andExpect(status().isNotFound()) + .andExpect(statusReason(equalTo(msgErrorNoFound("Alarm", alarm.getId().toString())))); testNotifyEntityNever(alarm.getId(), savedComment); } @@ -209,7 +210,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { .comment(JacksonUtil.newObjectNode().put("text", String.format("User %s deleted his comment", CUSTOMER_USER_EMAIL))) .build(); - testLogEntityAction(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); } @Test @@ -228,7 +229,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { .comment(JacksonUtil.newObjectNode().put("text", String.format("User %s deleted his comment", TENANT_ADMIN_EMAIL))) .build(); - testLogEntityAction(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); } @Test @@ -355,16 +356,18 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { Assert.assertTrue("Created alarm doesn't match the found one!", equals); } - private AlarmComment createAlarmComment(AlarmId alarmId, String text) { + private AlarmComment createAlarmComment(AlarmId alarmId, String text) { AlarmComment alarmComment = AlarmComment.builder() .comment(JacksonUtil.newObjectNode().set("text", new TextNode(text))) .build(); return saveAlarmComment(alarmId, alarmComment); } - private AlarmComment createAlarmComment(AlarmId alarmId) { + + private AlarmComment createAlarmComment(AlarmId alarmId) { return createAlarmComment(alarmId, "Please take a look"); } + private AlarmComment saveAlarmComment(AlarmId alarmId, AlarmComment alarmComment) { alarmComment = doPost("/api/alarm/" + alarmId + "/comment", alarmComment, AlarmComment.class); Assert.assertNotNull(alarmComment); From 1fe00ac46a1a7f6ef2a8ffa77d484acc067e4569 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 2 Jun 2023 19:37:16 +0300 Subject: [PATCH 121/207] UI: Implement widgets config basic mode. Widgets config minor refactoring. --- .../simple-card-basic-config.component.html | 42 --- .../simple-card-basic-config.component.ts | 58 ---- .../basic}/basic-config.scss | 0 .../basic}/basic-widget-config.module.ts | 2 +- .../simple-card-basic-config.component.html | 86 ++++++ .../simple-card-basic-config.component.ts | 110 ++++++++ .../widget-actions-panel.component.html | 0 .../common}/widget-actions-panel.component.ts | 0 .../data-key-config-dialog.component.html | 4 + .../data-key-config-dialog.component.scss | 0 .../data-key-config-dialog.component.ts | 4 + .../data-key-config.component.html | 8 +- .../data-key-config.component.scss | 0 .../{ => config}/data-key-config.component.ts | 17 ++ .../{ => config}/data-keys.component.html | 6 +- .../data-keys.component.models.ts | 0 .../{ => config}/data-keys.component.scss | 0 .../{ => config}/data-keys.component.ts | 24 +- .../{ => config}/datasource.component.html | 0 .../datasource.component.models.ts | 0 .../{ => config}/datasource.component.scss | 0 .../{ => config}/datasource.component.ts | 21 +- .../{ => config}/datasources.component.html | 0 .../{ => config}/datasources.component.scss | 0 .../{ => config}/datasources.component.ts | 17 ++ .../widget-config-components.module.ts | 6 + .../widget-config.component.models.ts | 0 .../widget/{ => config}/widget-config.scss | 45 +-- .../widget-settings.component.html | 0 .../widget-settings.component.scss | 0 .../{ => config}/widget-settings.component.ts | 25 +- .../trip-animation.component.html | 0 .../trip-animation.component.scss | 0 .../trip-animation.component.ts | 0 .../widget/widget-config.component.html | 31 +-- .../widget/widget-config.component.ts | 259 +++++++++--------- 36 files changed, 463 insertions(+), 302 deletions(-) delete mode 100644 ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html delete mode 100644 ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts rename ui-ngx/src/app/modules/home/components/widget/{basic-config => config/basic}/basic-config.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{basic-config => config/basic}/basic-widget-config.module.ts (96%) create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts rename ui-ngx/src/app/modules/home/components/widget/{basic-config/action => config/basic/common}/widget-actions-panel.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{basic-config/action => config/basic/common}/widget-actions-panel.component.ts (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-key-config-dialog.component.html (91%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-key-config-dialog.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-key-config-dialog.component.ts (96%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-key-config.component.html (97%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-key-config.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-key-config.component.ts (98%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-keys.component.html (97%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-keys.component.models.ts (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-keys.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/data-keys.component.ts (96%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/datasource.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/datasource.component.models.ts (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/datasource.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/datasource.component.ts (92%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/datasources.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/datasources.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/datasources.component.ts (97%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/widget-config-components.module.ts (87%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/widget-config.component.models.ts (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/widget-config.scss (85%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/widget-settings.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/widget-settings.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/widget-settings.component.ts (91%) rename ui-ngx/src/app/modules/home/components/widget/{ => lib}/trip-animation/trip-animation.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => lib}/trip-animation/trip-animation.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => lib}/trip-animation/trip-animation.component.ts (100%) diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html deleted file mode 100644 index a686add2fd..0000000000 --- a/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - -
-
widget-config.appearance
-
-
widgets.simple-card.label-position
- - - - {{ 'widgets.simple-card.label-position-left' | translate }} - - - {{ 'widgets.simple-card.label-position-top' | translate }} - - - -
-
- - -
diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts deleted file mode 100644 index f8cdaae59c..0000000000 --- a/ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -/// -/// Copyright © 2016-2023 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { Component } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { Store } from '@ngrx/store'; -import { AppState } from '@core/core.state'; -import { BasicWidgetConfigComponent } from '@home/components/widget/widget-config.component.models'; -import { WidgetConfigComponentData } from '@home/models/widget-component.models'; - -@Component({ - selector: 'tb-simple-card-basic-config', - templateUrl: './simple-card-basic-config.component.html', - styleUrls: ['../basic-config.scss', '../../widget-config.scss'] -}) -export class SimpleCardBasicConfigComponent extends BasicWidgetConfigComponent { - - simpleCardWidgetConfigForm: UntypedFormGroup; - - constructor(protected store: Store, - private fb: UntypedFormBuilder) { - super(store); - } - - protected configForm(): UntypedFormGroup { - return this.simpleCardWidgetConfigForm; - } - - protected onConfigSet(configData: WidgetConfigComponentData) { - this.simpleCardWidgetConfigForm = this.fb.group({ - datasources: [configData.config.datasources, []], - labelPosition: [configData.config.settings?.labelPosition, []], - actions: [configData.config.actions || {}, []] - }); - } - - protected prepareOutputConfig(config: any): WidgetConfigComponentData { - this.widgetConfig.config.datasources = this.simpleCardWidgetConfigForm.value.datasources; - this.widgetConfig.config.actions = this.simpleCardWidgetConfigForm.value.actions; - this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; - this.widgetConfig.config.settings.labelPosition = this.simpleCardWidgetConfigForm.value.labelPosition; - return this.widgetConfig; - } - -} diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-config.scss b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-config.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/basic-config/basic-config.scss rename to ui-ngx/src/app/modules/home/components/widget/config/basic/basic-config.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts similarity index 96% rename from ui-ngx/src/app/modules/home/components/widget/basic-config/basic-widget-config.module.ts rename to ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index 5d36fa43b3..b6f8fba834 100644 --- a/ui-ngx/src/app/modules/home/components/widget/basic-config/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -24,7 +24,7 @@ import { } from '@home/components/widget/basic-config/cards/simple-card-basic-config.component'; import { WidgetActionsPanelComponent -} from '@home/components/widget/basic-config/action/widget-actions-panel.component'; +} from '@home/components/widget/basic-config/common/widget-actions-panel.component'; @NgModule({ declarations: [ diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html new file mode 100644 index 0000000000..7ede72f4e4 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html @@ -0,0 +1,86 @@ + + + + + + +
+
widget-config.appearance
+
+
widgets.simple-card.label
+ + + +
+
+
widgets.simple-card.label-position
+ + + + {{ 'widgets.simple-card.label-position-left' | translate }} + + + {{ 'widgets.simple-card.label-position-top' | translate }} + + + +
+
+
widget-config.units-short
+ + + +
+
+
widget-config.decimals-short
+ + + +
+
+
{{ 'widget-config.text-color' | translate }}
+
+ + + +
+
+
+
{{ 'widget-config.background' | translate }}
+
+ + + +
+
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts new file mode 100644 index 0000000000..f27552f078 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts @@ -0,0 +1,110 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { + Datasource, + datasourcesHasAggregation, + datasourcesHasOnlyComparisonAggregation +} from '@shared/models/widget.models'; + +@Component({ + selector: 'tb-simple-card-basic-config', + templateUrl: './simple-card-basic-config.component.html', + styleUrls: ['../basic-config.scss', '../../widget-config.scss'] +}) +export class SimpleCardBasicConfigComponent extends BasicWidgetConfigComponent { + + public get displayTimewindowConfig(): boolean { + const datasources = this.simpleCardWidgetConfigForm.get('datasources').value; + return datasourcesHasAggregation(datasources); + } + + public onlyHistoryTimewindow(): boolean { + const datasources = this.simpleCardWidgetConfigForm.get('datasources').value; + return datasourcesHasOnlyComparisonAggregation(datasources); + } + + simpleCardWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + private fb: UntypedFormBuilder) { + super(store); + } + + protected configForm(): UntypedFormGroup { + return this.simpleCardWidgetConfigForm; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + this.simpleCardWidgetConfigForm = this.fb.group({ + timewindowConfig: [{ + useDashboardTimewindow: configData.config.useDashboardTimewindow, + displayTimewindow: configData.config.useDashboardTimewindow, + timewindow: configData.config.timewindow + }, []], + datasources: [configData.config.datasources, []], + label: [this.getDataKeyLabel(configData.config.datasources), []], + labelPosition: [configData.config.settings?.labelPosition, []], + units: [configData.config.units, []], + decimals: [configData.config.decimals, []], + color: [configData.config.color, []], + backgroundColor: [configData.config.backgroundColor, []], + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + this.widgetConfig.config.useDashboardTimewindow = config.timewindowConfig.useDashboardTimewindow; + this.widgetConfig.config.displayTimewindow = config.timewindowConfig.displayTimewindow; + this.widgetConfig.config.timewindow = config.timewindowConfig.timewindow; + this.widgetConfig.config.datasources = config.datasources; + this.setDataKeyLabel(config.label, this.widgetConfig.config.datasources); + this.widgetConfig.config.actions = config.actions; + this.widgetConfig.config.units = config.units; + this.widgetConfig.config.decimals = config.decimals; + this.widgetConfig.config.color = config.color; + this.widgetConfig.config.backgroundColor = config.backgroundColor; + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + this.widgetConfig.config.settings.labelPosition = config.labelPosition; + return this.widgetConfig; + } + + private getDataKeyLabel(datasources?: Datasource[]): string { + if (datasources && datasources.length) { + const dataKeys = datasources[0].dataKeys; + if (dataKeys && dataKeys.length) { + return dataKeys[0].label; + } + } + return ''; + } + + private setDataKeyLabel(label: string, datasources?: Datasource[]) { + if (datasources && datasources.length) { + const dataKeys = datasources[0].dataKeys; + if (dataKeys && dataKeys.length) { + dataKeys[0].label = label; + } + } + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.html diff --git a/ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.html similarity index 91% rename from ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.html index 6cd6679934..354008393e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.html @@ -40,6 +40,10 @@ [widgetType]="data.widgetType" [showPostProcessing]="data.showPostProcessing" [callbacks]="data.callbacks" + [hideDataKeyLabel]="data.hideDataKeyLabel" + [hideDataKeyColor]="data.hideDataKeyColor" + [hideDataKeyUnits]="data.hideDataKeyUnits" + [hideDataKeyDecimals]="data.hideDataKeyDecimals" formControlName="dataKey">
diff --git a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.scss rename to ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts similarity index 96% rename from ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts index e305495d08..24aca1800e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts @@ -40,6 +40,10 @@ export interface DataKeyConfigDialogData { entityAliasId?: string; showPostProcessing?: boolean; callbacks?: DataKeysCallbacks; + hideDataKeyLabel: boolean; + hideDataKeyColor: boolean; + hideDataKeyUnits: boolean; + hideDataKeyDecimals: boolean; } @Component({ diff --git a/ui-ngx/src/app/modules/home/components/widget/data-key-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html similarity index 97% rename from ui-ngx/src/app/modules/home/components/widget/data-key-config.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html index 2f27726d90..daf70c19e4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-key-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html @@ -40,11 +40,11 @@
- + datakey.label -
- + datakey.units - + datakey.decimals diff --git a/ui-ngx/src/app/modules/home/components/widget/data-key-config.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/data-key-config.component.scss rename to ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/data-key-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts similarity index 98% rename from ui-ngx/src/app/modules/home/components/widget/data-key-config.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts index d0069f34ee..c1e1911638 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-key-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts @@ -52,6 +52,7 @@ import { Dashboard } from '@shared/models/dashboard.models'; import { IAliasController } from '@core/api/widget-api.models'; import { aggregationTranslations, AggregationType, ComparisonDuration } from '@shared/models/time/time.models'; import { genNextLabel } from '@core/utils'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-data-key-config', @@ -120,6 +121,22 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con @Input() showPostProcessing = true; + @Input() + @coerceBoolean() + hideDataKeyLabel = false; + + @Input() + @coerceBoolean() + hideDataKeyColor = false; + + @Input() + @coerceBoolean() + hideDataKeyUnits = false; + + @Input() + @coerceBoolean() + hideDataKeyDecimals = false; + @ViewChild('keyInput') keyInput: ElementRef; @ViewChild('funcBodyEdit') funcBodyEdit: JsFuncComponent; diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.html b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.html similarity index 97% rename from ui-ngx/src/app/modules/home/components/widget/data-keys.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.html index 79a97e071f..39fffd79e7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.html @@ -62,16 +62,16 @@ matTooltip="{{'datakey.timeseries' | translate }}" matTooltipPosition="above">timeline - {{key.label}} + {{key.label}}
-
:
+
:
-
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.models.ts similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/data-keys.component.models.ts rename to ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.models.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss rename to ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts similarity index 96% rename from ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts index 5e4dafe6cf..a4d11dc1de 100644 --- a/ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts @@ -68,6 +68,7 @@ import { AggregationType } from '@shared/models/time/time.models'; import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive'; import { moveItemInArray } from '@angular/cdk/drag-drop'; import { coerceBoolean } from '@shared/decorators/coercion'; +import { DatasourceComponent } from '@home/components/widget/datasource.component'; @Component({ selector: 'tb-data-keys', @@ -88,6 +89,22 @@ import { coerceBoolean } from '@shared/decorators/coercion'; }) export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChanges, ErrorStateMatcher { + public get hideDataKeyLabel(): boolean { + return this.datasourceComponent.hideDataKeyLabel; + } + + public get hideDataKeyColor(): boolean { + return this.datasourceComponent.hideDataKeyColor; + } + + public get hideDataKeyUnits(): boolean { + return this.datasourceComponent.hideDataKeyUnits; + } + + public get hideDataKeyDecimals(): boolean { + return this.datasourceComponent.hideDataKeyDecimals; + } + datasourceTypes = DatasourceType; widgetTypes = widgetType; dataKeyTypes = DataKeyType; @@ -188,6 +205,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange constructor(private store: Store, @SkipSelf() private errorStateMatcher: ErrorStateMatcher, + private datasourceComponent: DatasourceComponent, public translate: TranslateService, private utils: UtilsService, private dialogs: DialogService, @@ -480,7 +498,11 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange deviceId: this.deviceId, entityAliasId: this.entityAliasId, showPostProcessing: this.widgetType !== widgetType.alarm, - callbacks: this.callbacks + callbacks: this.callbacks, + hideDataKeyLabel: this.hideDataKeyLabel, + hideDataKeyColor: this.hideDataKeyColor, + hideDataKeyUnits: this.hideDataKeyUnits, + hideDataKeyDecimals: this.hideDataKeyDecimals } }).afterClosed().subscribe((updatedDataKey) => { if (updatedDataKey) { diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.html b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/datasource.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.models.ts similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/datasource.component.models.ts rename to ui-ngx/src/app/modules/home/components/widget/config/datasource.component.models.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/datasource.component.scss rename to ui-ngx/src/app/modules/home/components/widget/config/datasource.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts similarity index 92% rename from ui-ngx/src/app/modules/home/components/widget/datasource.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts index 79adc363a6..a3e3fc7c26 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasource.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { Component, forwardRef, Input, OnInit, Optional } from '@angular/core'; import { ControlValueAccessor, NG_VALIDATORS, @@ -41,6 +41,7 @@ import { EntityAliasSelectCallbacks } from '@home/components/alias/entity-alias- import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models'; import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; import { EntityType } from '@shared/models/entity-type.models'; +import { DatasourcesComponent } from '@home/components/widget/datasources.component'; @Component({ selector: 'tb-datasource', @@ -122,6 +123,22 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida return this.widgetConfigComponent.widget; } + public get hideDataKeyLabel(): boolean { + return this.datasourcesComponent?.hideDataKeyLabel; + } + + public get hideDataKeyColor(): boolean { + return this.datasourcesComponent?.hideDataKeyColor; + } + + public get hideDataKeyUnits(): boolean { + return this.datasourcesComponent?.hideDataKeyUnits; + } + + public get hideDataKeyDecimals(): boolean { + return this.datasourcesComponent?.hideDataKeyDecimals; + } + @Input() disabled: boolean; @@ -138,6 +155,8 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida private propagateChange = (_val: any) => {}; constructor(private fb: UntypedFormBuilder, + @Optional() + private datasourcesComponent: DatasourcesComponent, private widgetConfigComponent: WidgetConfigComponent) { } diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.html b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/datasources.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/datasources.component.html diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/datasources.component.scss rename to ui-ngx/src/app/modules/home/components/widget/config/datasources.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts similarity index 97% rename from ui-ngx/src/app/modules/home/components/widget/datasources.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts index f47adfb2a9..dc62b0e25e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/datasources.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts @@ -41,6 +41,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { UtilsService } from '@core/services/utils.service'; import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; import { TranslateService } from '@ngx-translate/core'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-datasources', @@ -87,6 +88,22 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid @Input() disabled: boolean; + @Input() + @coerceBoolean() + hideDataKeyLabel = false; + + @Input() + @coerceBoolean() + hideDataKeyColor = false; + + @Input() + @coerceBoolean() + hideDataKeyUnits = false; + + @Input() + @coerceBoolean() + hideDataKeyDecimals = false; + @Input() configMode: WidgetConfigMode; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts similarity index 87% rename from ui-ngx/src/app/modules/home/components/widget/widget-config-components.module.ts rename to ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts index 56302e212d..c5a114d763 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts @@ -18,6 +18,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@app/shared/shared.module'; import { AlarmFilterConfigComponent } from '@home/components/alarm/alarm-filter-config.component'; +import { AlarmAssigneeSelectComponent } from '@home/components/alarm/alarm-assignee-select.component'; import { DataKeysComponent } from '@home/components/widget/data-keys.component'; import { DataKeyConfigDialogComponent } from '@home/components/widget/data-key-config-dialog.component'; import { DataKeyConfigComponent } from '@home/components/widget/data-key-config.component'; @@ -27,10 +28,12 @@ import { EntityAliasSelectComponent } from '@home/components/alias/entity-alias- import { FilterSelectComponent } from '@home/components/filter/filter-select.component'; import { WidgetSettingsModule } from '@home/components/widget/lib/settings/widget-settings.module'; import { WidgetSettingsComponent } from '@home/components/widget/widget-settings.component'; +import { TimewindowConfigPanelComponent } from '@home/components/widget/timewindow-config-panel.component'; @NgModule({ declarations: [ + AlarmAssigneeSelectComponent, AlarmFilterConfigComponent, DataKeysComponent, DataKeyConfigDialogComponent, @@ -39,6 +42,7 @@ import { WidgetSettingsComponent } from '@home/components/widget/widget-settings DatasourcesComponent, EntityAliasSelectComponent, FilterSelectComponent, + TimewindowConfigPanelComponent, WidgetSettingsComponent ], imports: [ @@ -47,6 +51,7 @@ import { WidgetSettingsComponent } from '@home/components/widget/widget-settings WidgetSettingsModule ], exports: [ + AlarmAssigneeSelectComponent, AlarmFilterConfigComponent, DataKeysComponent, DataKeyConfigDialogComponent, @@ -55,6 +60,7 @@ import { WidgetSettingsComponent } from '@home/components/widget/widget-settings DatasourcesComponent, EntityAliasSelectComponent, FilterSelectComponent, + TimewindowConfigPanelComponent, WidgetSettingsComponent ] }) diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts rename to ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.scss b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss similarity index 85% rename from ui-ngx/src/app/modules/home/components/widget/widget-config.scss rename to ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss index bc269e5a67..15e14e211e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.scss +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss @@ -80,6 +80,30 @@ } } + .mat-mdc-form-field { + &.center { + .mat-mdc-text-field-wrapper.mdc-text-field--outlined { + .mat-mdc-form-field-infix { + .mdc-text-field__input { + text-align: center; + } + } + } + } + &.number { + .mat-mdc-text-field-wrapper.mdc-text-field--outlined { + padding-right: 4px; + .mat-mdc-form-field-infix { + width: 80px; + input.mdc-text-field__input[type=number]::-webkit-inner-spin-button, + input.mdc-text-field__input[type=number]::-webkit-outer-spin-button { + opacity: 1; + } + } + } + } + } + .tb-widget-config-row { .mat-mdc-form-field { .mat-mdc-text-field-wrapper.mdc-text-field--outlined { @@ -97,27 +121,6 @@ width: 72px; } } - &.center { - .mat-mdc-text-field-wrapper.mdc-text-field--outlined { - .mat-mdc-form-field-infix { - .mdc-text-field__input { - text-align: center; - } - } - } - } - &.number { - .mat-mdc-text-field-wrapper.mdc-text-field--outlined { - padding-right: 4px; - .mat-mdc-form-field-infix { - width: 80px; - input.mdc-text-field__input[type=number]::-webkit-inner-spin-button, - input.mdc-text-field__input[type=number]::-webkit-outer-spin-button { - opacity: 1; - } - } - } - } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/widget-settings.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.html diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-settings.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/widget-settings.component.scss rename to ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.ts similarity index 91% rename from ui-ngx/src/app/modules/home/components/widget/widget-settings.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.ts index 7bfb66fd61..cc482bfd4e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.ts @@ -16,28 +16,27 @@ import { AfterViewInit, - Component, ComponentFactoryResolver, + Component, + ComponentFactoryResolver, ComponentRef, forwardRef, - Input, OnChanges, + Input, + OnChanges, OnDestroy, - OnInit, SimpleChanges, + OnInit, + SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core'; -import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; import { - IRuleNodeConfigurationComponent, - RuleNodeConfiguration, - RuleNodeDefinition -} from '@shared/models/rule-node.models'; + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormGroup, + Validators +} from '@angular/forms'; import { Subscription } from 'rxjs'; -import { RuleChainService } from '@core/http/rule-chain.service'; -import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { TranslateService } from '@ngx-translate/core'; -import { JsonObjectEditComponent } from '@shared/components/json-object-edit.component'; -import { deepClone } from '@core/utils'; -import { RuleChainType } from '@shared/models/rule-chain.models'; import { JsonFormComponent } from '@shared/components/json-form/json-form.component'; import { JsonFormComponentData } from '@shared/components/json-form/json-form-component.models'; import { IWidgetSettingsComponent, Widget, WidgetSettings } from '@shared/models/widget.models'; diff --git a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.html rename to ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.html diff --git a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.scss rename to ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.ts similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts rename to ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html index cde8205f62..86f2cba04e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html @@ -199,31 +199,12 @@
-
-
-
timewindow.timewindow
- - -
-
- - - {{ 'widget-config.display-timewindow' | translate }} - -
-
+ + + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index d42f441c7c..057558f9b8 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -65,7 +65,7 @@ import { Observable, of, Subscription } from 'rxjs'; import { IBasicWidgetConfigComponent, WidgetConfigCallbacks -} from '@home/components/widget/widget-config.component.models'; +} from '@home/components/widget/config/widget-config.component.models'; import { EntityAliasDialogComponent, EntityAliasDialogData @@ -80,8 +80,9 @@ import { Filter, singleEntityFilterFromDeviceId } from '@shared/models/query/que import { FilterDialogComponent, FilterDialogData } from '@home/components/filter/filter-dialog.component'; import { ToggleHeaderOption } from '@shared/components/toggle-header.component'; import { coerceBoolean } from '@shared/decorators/coercion'; -import { basicWidgetConfigComponentsMap } from '@home/components/widget/basic-config/basic-widget-config.module'; +import { basicWidgetConfigComponentsMap } from '@home/components/widget/config/basic/basic-widget-config.module'; import Timeout = NodeJS.Timeout; +import { TimewindowConfigData } from '@home/components/widget/timewindow-config-panel.component'; const emptySettingsSchema: JsonSchema = { type: 'object', @@ -188,6 +189,8 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private advancedSettingsSubscription: Subscription; private actionsSettingsSubscription: Subscription; + private defaultConfigFormsType: widgetType; + constructor(protected store: Store, private utils: UtilsService, private entityService: EntityService, @@ -356,12 +359,11 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.targetDeviceSettings = this.fb.group({}); this.advancedSettings = this.fb.group({}); if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) { - this.dataSettings.addControl('useDashboardTimewindow', this.fb.control(true)); - this.dataSettings.addControl('displayTimewindow', this.fb.control({value: true, disabled: true})); - this.dataSettings.addControl('timewindow', this.fb.control({value: null, disabled: true})); - this.dataSettings.get('useDashboardTimewindow').valueChanges.subscribe(() => { - this.updateDataSettingsEnabledState(); - }); + this.dataSettings.addControl('timewindowConfig', this.fb.control({ + useDashboardTimewindow: true, + displayTimewindow: true, + timewindow: null + })); if (this.widgetType === widgetType.alarm) { this.dataSettings.addControl('alarmFilterConfig', this.fb.control(null)); } @@ -396,16 +398,19 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe writeValue(value: WidgetConfigComponentData): void { this.modelValue = value; + this.widgetType = this.modelValue?.widgetType; this.setupConfig(); } private setupConfig() { - this.destroyBasicModeComponent(); - this.removeChangeSubscriptions(); - if (this.hasBasicModeDirective && this.widgetConfigMode === WidgetConfigMode.basic) { - this.setupBasicModeConfig(); - } else { - this.setupDefaultConfig(); + if (this.modelValue) { + this.destroyBasicModeComponent(); + this.removeChangeSubscriptions(); + if (this.hasBasicModeDirective && this.widgetConfigMode === WidgetConfigMode.basic) { + this.setupBasicModeConfig(); + } else { + this.setupDefaultConfig(); + } } } @@ -451,123 +456,116 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } private setupDefaultConfig() { - if (this.modelValue) { - if (this.widgetType !== this.modelValue.widgetType) { - this.widgetType = this.modelValue.widgetType; - this.buildForms(); + if (this.defaultConfigFormsType !== this.widgetType) { + this.defaultConfigFormsType = this.widgetType; + this.buildForms(); + } + this.buildHeader(); + const config = this.modelValue.config; + const layout = this.modelValue.layout; + if (config) { + const displayWidgetTitle = isDefined(config.showTitle) ? config.showTitle : false; + this.widgetSettings.patchValue({ + title: config.title, + showTitleIcon: isDefined(config.showTitleIcon) && displayWidgetTitle ? config.showTitleIcon : false, + titleIcon: isDefined(config.titleIcon) ? config.titleIcon : '', + iconColor: isDefined(config.iconColor) ? config.iconColor : 'rgba(0, 0, 0, 0.87)', + iconSize: isDefined(config.iconSize) ? config.iconSize : '24px', + titleTooltip: isDefined(config.titleTooltip) ? config.titleTooltip : '', + showTitle: displayWidgetTitle, + dropShadow: isDefined(config.dropShadow) ? config.dropShadow : true, + enableFullscreen: isDefined(config.enableFullscreen) ? config.enableFullscreen : true, + backgroundColor: config.backgroundColor, + color: config.color, + padding: config.padding, + margin: config.margin, + widgetStyle: isDefined(config.widgetStyle) ? config.widgetStyle : {}, + widgetCss: isDefined(config.widgetCss) ? config.widgetCss : '', + titleStyle: isDefined(config.titleStyle) ? config.titleStyle : { + fontSize: '16px', + fontWeight: 400 + }, + pageSize: isDefined(config.pageSize) ? config.pageSize : 1024, + units: config.units, + decimals: config.decimals, + noDataDisplayMessage: isDefined(config.noDataDisplayMessage) ? config.noDataDisplayMessage : '' + }, + {emitEvent: false} + ); + this.updateWidgetSettingsEnabledState(); + this.actionsSettings.patchValue( + { + actions: config.actions || {} + }, + {emitEvent: false} + ); + if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) { + const useDashboardTimewindow = isDefined(config.useDashboardTimewindow) ? + config.useDashboardTimewindow : true; + this.dataSettings.get('timewindowConfig').patchValue({ + useDashboardTimewindow, + displayTimewindow: isDefined(config.displayTimewindow) ? + config.displayTimewindow : true, + timewindow: config.timewindow + }, {emitEvent: false}); } - this.buildHeader(); - const config = this.modelValue.config; - const layout = this.modelValue.layout; - if (config) { - const displayWidgetTitle = isDefined(config.showTitle) ? config.showTitle : false; - this.widgetSettings.patchValue({ - title: config.title, - showTitleIcon: isDefined(config.showTitleIcon) && displayWidgetTitle ? config.showTitleIcon : false, - titleIcon: isDefined(config.titleIcon) ? config.titleIcon : '', - iconColor: isDefined(config.iconColor) ? config.iconColor : 'rgba(0, 0, 0, 0.87)', - iconSize: isDefined(config.iconSize) ? config.iconSize : '24px', - titleTooltip: isDefined(config.titleTooltip) ? config.titleTooltip : '', - showTitle: displayWidgetTitle, - dropShadow: isDefined(config.dropShadow) ? config.dropShadow : true, - enableFullscreen: isDefined(config.enableFullscreen) ? config.enableFullscreen : true, - backgroundColor: config.backgroundColor, - color: config.color, - padding: config.padding, - margin: config.margin, - widgetStyle: isDefined(config.widgetStyle) ? config.widgetStyle : {}, - widgetCss: isDefined(config.widgetCss) ? config.widgetCss : '', - titleStyle: isDefined(config.titleStyle) ? config.titleStyle : { - fontSize: '16px', - fontWeight: 400 - }, - pageSize: isDefined(config.pageSize) ? config.pageSize : 1024, - units: config.units, - decimals: config.decimals, - noDataDisplayMessage: isDefined(config.noDataDisplayMessage) ? config.noDataDisplayMessage : '' + if (this.modelValue.isDataEnabled) { + if (this.widgetType !== widgetType.rpc && + this.widgetType !== widgetType.alarm && + this.widgetType !== widgetType.static) { + this.dataSettings.patchValue({ datasources: config.datasources}, + {emitEvent: false}); + } else if (this.widgetType === widgetType.rpc) { + let targetDeviceAliasId: string; + if (config.targetDeviceAliasIds && config.targetDeviceAliasIds.length > 0) { + const aliasId = config.targetDeviceAliasIds[0]; + const entityAliases = this.aliasController.getEntityAliases(); + if (entityAliases[aliasId]) { + targetDeviceAliasId = entityAliases[aliasId].id; + } else { + targetDeviceAliasId = null; + } + } else { + targetDeviceAliasId = null; + } + this.targetDeviceSettings.patchValue({ + targetDeviceAliasId + }, {emitEvent: false}); + } else if (this.widgetType === widgetType.alarm) { + this.dataSettings.patchValue( + { alarmFilterConfig: isDefined(config.alarmFilterConfig) ? + config.alarmFilterConfig : + { statusList: [AlarmSearchStatus.ACTIVE], searchPropagatedAlarms: true }, + alarmSource: config.alarmSource }, {emitEvent: false} + ); + } + } + + this.updateSchemaForm(config.settings); + + if (layout) { + this.layoutSettings.patchValue( + { + mobileOrder: layout.mobileOrder, + mobileHeight: layout.mobileHeight, + mobileHide: layout.mobileHide, + desktopHide: layout.desktopHide }, {emitEvent: false} ); - this.updateWidgetSettingsEnabledState(); - this.actionsSettings.patchValue( + } else { + this.layoutSettings.patchValue( { - actions: config.actions || {} + mobileOrder: null, + mobileHeight: null, + mobileHide: false, + desktopHide: false }, {emitEvent: false} ); - if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) { - const useDashboardTimewindow = isDefined(config.useDashboardTimewindow) ? - config.useDashboardTimewindow : true; - this.dataSettings.patchValue( - { useDashboardTimewindow }, {emitEvent: false} - ); - this.dataSettings.patchValue( - { displayTimewindow: isDefined(config.displayTimewindow) ? - config.displayTimewindow : true }, {emitEvent: false} - ); - this.dataSettings.patchValue( - { timewindow: config.timewindow }, {emitEvent: false} - ); - this.updateDataSettingsEnabledState(); - } - if (this.modelValue.isDataEnabled) { - if (this.widgetType !== widgetType.rpc && - this.widgetType !== widgetType.alarm && - this.widgetType !== widgetType.static) { - this.dataSettings.patchValue({ datasources: config.datasources}, - {emitEvent: false}); - } else if (this.widgetType === widgetType.rpc) { - let targetDeviceAliasId: string; - if (config.targetDeviceAliasIds && config.targetDeviceAliasIds.length > 0) { - const aliasId = config.targetDeviceAliasIds[0]; - const entityAliases = this.aliasController.getEntityAliases(); - if (entityAliases[aliasId]) { - targetDeviceAliasId = entityAliases[aliasId].id; - } else { - targetDeviceAliasId = null; - } - } else { - targetDeviceAliasId = null; - } - this.targetDeviceSettings.patchValue({ - targetDeviceAliasId - }, {emitEvent: false}); - } else if (this.widgetType === widgetType.alarm) { - this.dataSettings.patchValue( - { alarmFilterConfig: isDefined(config.alarmFilterConfig) ? - config.alarmFilterConfig : - { statusList: [AlarmSearchStatus.ACTIVE], searchPropagatedAlarms: true }, - alarmSource: config.alarmSource }, {emitEvent: false} - ); - } - } - - this.updateSchemaForm(config.settings); - - if (layout) { - this.layoutSettings.patchValue( - { - mobileOrder: layout.mobileOrder, - mobileHeight: layout.mobileHeight, - mobileHide: layout.mobileHide, - desktopHide: layout.desktopHide - }, - {emitEvent: false} - ); - } else { - this.layoutSettings.patchValue( - { - mobileOrder: null, - mobileHeight: null, - mobileHide: false, - desktopHide: false - }, - {emitEvent: false} - ); - } } - this.createChangeSubscriptions(); } + this.createChangeSubscriptions(); } private updateWidgetSettingsEnabledState() { @@ -595,17 +593,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe } } - private updateDataSettingsEnabledState() { - const useDashboardTimewindow: boolean = this.dataSettings.get('useDashboardTimewindow').value; - if (useDashboardTimewindow) { - this.dataSettings.get('displayTimewindow').disable({emitEvent: false}); - this.dataSettings.get('timewindow').disable({emitEvent: false}); - } else { - this.dataSettings.get('displayTimewindow').enable({emitEvent: false}); - this.dataSettings.get('timewindow').enable({emitEvent: false}); - } - } - private updateSchemaForm(settings?: any) { const widgetSettingsFormData: JsonFormComponentData = {}; if (this.modelValue.settingsSchema && this.modelValue.settingsSchema.schema) { @@ -626,7 +613,13 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private updateDataSettings() { if (this.modelValue) { if (this.modelValue.config) { - Object.assign(this.modelValue.config, this.dataSettings.value); + let data = this.dataSettings.value; + if (data.timewindowConfig) { + const timewindowConfig: TimewindowConfigData = data.timewindowConfig; + data = {...data, ...timewindowConfig}; + delete data.timewindowConfig; + } + Object.assign(this.modelValue.config, data); } this.propagateChange(this.modelValue); } From 7a342884bfb779a72eda17cc96a9340887156085 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 2 Jun 2023 19:43:13 +0300 Subject: [PATCH 122/207] UI: Implement widgets config basic mode. Widgets config minor refactoring. --- ui-ngx/src/app/modules/common/modules-map.ts | 12 +- .../home/components/home-components.module.ts | 7 +- .../basic/basic-widget-config.module.ts | 8 +- .../simple-card-basic-config.component.html | 6 +- .../simple-card-basic-config.component.ts | 2 +- .../common/widget-actions-panel.component.ts | 10 +- .../data-key-config-dialog.component.ts | 2 +- .../config/data-key-config.component.scss | 2 +- .../config/data-key-config.component.ts | 2 +- .../widget/config/data-keys.component.ts | 4 +- .../config/datasource.component.models.ts | 2 +- .../widget/config/datasource.component.ts | 4 +- .../widget/config/datasources.component.scss | 2 +- .../widget/config/datasources.component.ts | 4 +- .../timewindow-config-panel.component.html | 42 +++++++ .../timewindow-config-panel.component.ts | 115 ++++++++++++++++++ .../config/widget-config-components.module.ts | 17 +-- .../config/widget-config.component.models.ts | 4 +- .../widget/config/widget-units.component.html | 20 +++ .../widget/config/widget-units.component.ts | 67 ++++++++++ .../simple-card-widget-settings.component.ts | 2 +- .../widget/widget-component.service.ts | 2 +- .../widget/widget-components.module.ts | 2 +- .../widget/widget-config.component.html | 6 +- .../widget/widget-config.component.ts | 4 +- .../assets/locale/locale.constant-en_US.json | 2 + 26 files changed, 295 insertions(+), 55 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.ts diff --git a/ui-ngx/src/app/modules/common/modules-map.ts b/ui-ngx/src/app/modules/common/modules-map.ts index 8d64384ab0..b3a14b0f61 100644 --- a/ui-ngx/src/app/modules/common/modules-map.ts +++ b/ui-ngx/src/app/modules/common/modules-map.ts @@ -206,9 +206,9 @@ import * as EntityAliasDialogComponent from '@home/components/alias/entity-alias import * as EntityFilterComponent from '@home/components/entity/entity-filter.component'; import * as RelationFiltersComponent from '@home/components/relation/relation-filters.component'; import * as EntityAliasSelectComponent from '@home/components/alias/entity-alias-select.component'; -import * as DataKeysComponent from '@home/components/widget/data-keys.component'; -import * as DataKeyConfigDialogComponent from '@home/components/widget/data-key-config-dialog.component'; -import * as DataKeyConfigComponent from '@home/components/widget/data-key-config.component'; +import * as DataKeysComponent from '@home/components/widget/config/data-keys.component'; +import * as DataKeyConfigDialogComponent from '@home/components/widget/config/data-key-config-dialog.component'; +import * as DataKeyConfigComponent from '@home/components/widget/config/data-key-config.component'; import * as LegendConfigComponent from '@home/components/widget/lib/settings/common/legend-config.component'; import * as ManageWidgetActionsComponent from '@home/components/widget/action/manage-widget-actions.component'; import * as WidgetActionDialogComponent from '@home/components/widget/action/widget-action-dialog.component'; @@ -501,9 +501,9 @@ class ModulesMap implements IModulesMap { '@home/components/entity/entity-filter.component': EntityFilterComponent, '@home/components/relation/relation-filters.component': RelationFiltersComponent, '@home/components/alias/entity-alias-select.component': EntityAliasSelectComponent, - '@home/components/widget/data-keys.component': DataKeysComponent, - '@home/components/widget/data-key-config-dialog.component': DataKeyConfigDialogComponent, - '@home/components/widget/data-key-config.component': DataKeyConfigComponent, + '@home/components/widget/config/data-keys.component': DataKeysComponent, + '@home/components/widget/config/data-key-config-dialog.component': DataKeyConfigDialogComponent, + '@home/components/widget/config/data-key-config.component': DataKeyConfigComponent, '@home/components/widget/lib/settings/common/legend-config.component': LegendConfigComponent, '@home/components/widget/action/manage-widget-actions.component': ManageWidgetActionsComponent, '@home/components/widget/action/widget-action-dialog.component': WidgetActionDialogComponent, diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index a2d18dfa34..a6e2cc03dc 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -170,14 +170,13 @@ import { AlarmAssigneePanelComponent } from '@home/components/alarm/alarm-assign import { RouterTabsComponent } from '@home/components/router-tabs.component'; import { SendNotificationButtonComponent } from '@home/components/notification/send-notification-button.component'; import { AlarmAssigneeSelectPanelComponent } from '@home/components/alarm/alarm-assignee-select-panel.component'; -import { AlarmAssigneeSelectComponent } from '@home/components/alarm/alarm-assignee-select.component'; import { DeviceInfoFilterComponent } from '@home/components/device/device-info-filter.component'; import { WidgetPreviewComponent } from '@home/components/widget/widget-preview.component'; import { ManageWidgetActionsDialogComponent } from '@home/components/widget/action/manage-widget-actions-dialog.component'; -import { WidgetConfigComponentsModule } from '@home/components/widget/widget-config-components.module'; -import { BasicWidgetConfigModule } from '@home/components/widget/basic-config/basic-widget-config.module'; +import { WidgetConfigComponentsModule } from '@home/components/widget/config/widget-config-components.module'; +import { BasicWidgetConfigModule } from '@home/components/widget/config/basic/basic-widget-config.module'; @NgModule({ declarations: @@ -202,7 +201,6 @@ import { BasicWidgetConfigModule } from '@home/components/widget/basic-config/ba AlarmTableHeaderComponent, AlarmTableComponent, AlarmAssigneePanelComponent, - AlarmAssigneeSelectComponent, AlarmAssigneeSelectPanelComponent, AttributeTableComponent, AddAttributeDialogComponent, @@ -350,7 +348,6 @@ import { BasicWidgetConfigModule } from '@home/components/widget/basic-config/ba RelationFiltersComponent, AlarmTableComponent, AlarmAssigneePanelComponent, - AlarmAssigneeSelectComponent, AlarmAssigneeSelectPanelComponent, AttributeTableComponent, AliasesEntitySelectComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index b6f8fba834..e7d0d58b13 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -17,14 +17,14 @@ import { NgModule, Type } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@shared/shared.module'; -import { IBasicWidgetConfigComponent } from '@home/components/widget/widget-config.component.models'; -import { WidgetConfigComponentsModule } from '@home/components/widget/widget-config-components.module'; +import { IBasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentsModule } from '@home/components/widget/config/widget-config-components.module'; import { SimpleCardBasicConfigComponent -} from '@home/components/widget/basic-config/cards/simple-card-basic-config.component'; +} from '@home/components/widget/config/basic/cards/simple-card-basic-config.component'; import { WidgetActionsPanelComponent -} from '@home/components/widget/basic-config/common/widget-actions-panel.component'; +} from '@home/components/widget/config/basic/common/widget-actions-panel.component'; @NgModule({ declarations: [ diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html index 7ede72f4e4..28cd0aaa6e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html @@ -51,9 +51,9 @@
widget-config.units-short
- - - + +
widget-config.decimals-short
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts index f27552f078..62d25249e9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts @@ -18,7 +18,7 @@ import { Component } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { BasicWidgetConfigComponent } from '@home/components/widget/widget-config.component.models'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; import { WidgetConfigComponentData } from '@home/models/widget-component.models'; import { Datasource, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts index 02d9787aa7..68dfca5858 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts @@ -15,16 +15,10 @@ /// import { ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core'; -import { - ControlValueAccessor, - NG_VALIDATORS, - NG_VALUE_ACCESSOR, - UntypedFormBuilder, - UntypedFormGroup -} from '@angular/forms'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; import { WidgetActionsData } from '@home/components/widget/action/manage-widget-actions.component.models'; -import { Datasource, WidgetActionDescriptor } from '@shared/models/widget.models'; +import { WidgetActionDescriptor } from '@shared/models/widget.models'; import { ManageWidgetActionsDialogComponent, ManageWidgetActionsDialogData diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts index 24aca1800e..d2bdd2f8a1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts @@ -24,7 +24,7 @@ import { Router } from '@angular/router'; import { DialogComponent } from '@shared/components/dialog.component'; import { DataKey, Widget, widgetType } from '@shared/models/widget.models'; import { DataKeysCallbacks } from './data-keys.component.models'; -import { DataKeyConfigComponent } from '@home/components/widget/data-key-config.component'; +import { DataKeyConfigComponent } from '@home/components/widget/config/data-key-config.component'; import { Dashboard } from '@shared/models/dashboard.models'; import { IAliasController } from '@core/api/widget-api.models'; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss index e5f6c02ef7..2ef3488e53 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -@import '../../../../../scss/constants'; +@import '../../../../../../scss/constants'; :host { .tb-datakey-config { diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts index c1e1911638..9d9201e88a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts @@ -40,7 +40,7 @@ import { UtilsService } from '@core/services/utils.service'; import { TranslateService } from '@ngx-translate/core'; import { MatDialog } from '@angular/material/dialog'; import { EntityService } from '@core/http/entity.service'; -import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; +import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { Observable, of } from 'rxjs'; import { map, mergeMap, publishReplay, refCount, tap } from 'rxjs/operators'; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts index a4d11dc1de..95fe5bc444 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts @@ -61,14 +61,14 @@ import { MatDialog } from '@angular/material/dialog'; import { DataKeyConfigDialogComponent, DataKeyConfigDialogData -} from '@home/components/widget/data-key-config-dialog.component'; +} from '@home/components/widget/config/data-key-config-dialog.component'; import { deepClone, guid, isDefinedAndNotNull, isUndefined } from '@core/utils'; import { Dashboard } from '@shared/models/dashboard.models'; import { AggregationType } from '@shared/models/time/time.models'; import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive'; import { moveItemInArray } from '@angular/cdk/drag-drop'; import { coerceBoolean } from '@shared/decorators/coercion'; -import { DatasourceComponent } from '@home/components/widget/datasource.component'; +import { DatasourceComponent } from '@home/components/widget/config/datasource.component'; @Component({ selector: 'tb-data-keys', diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.models.ts index 208cdd7b47..0664058fb4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.models.ts @@ -16,6 +16,6 @@ import { EntityAliasSelectCallbacks } from '@home/components/alias/entity-alias-select.component.models'; import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models'; -import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; +import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; export type DatasourceCallbacks = EntityAliasSelectCallbacks & FilterSelectCallbacks & DataKeysCallbacks; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts index a3e3fc7c26..6fca263c53 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts @@ -39,9 +39,9 @@ import { WidgetConfigComponent } from '@home/components/widget/widget-config.com import { IAliasController } from '@core/api/widget-api.models'; import { EntityAliasSelectCallbacks } from '@home/components/alias/entity-alias-select.component.models'; import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models'; -import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; +import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; import { EntityType } from '@shared/models/entity-type.models'; -import { DatasourcesComponent } from '@home/components/widget/datasources.component'; +import { DatasourcesComponent } from '@home/components/widget/config/datasources.component'; @Component({ selector: 'tb-datasource', diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.scss index 8be2eeadbf..5b356afcf2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.scss @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -@import "../../../../../theme"; +@import "../../../../../../theme"; .tb-datasource-list-item { &.mat-mdc-list-item { diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts index dc62b0e25e..383b9e15ee 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts @@ -39,14 +39,14 @@ import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { deepClone } from '@core/utils'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { UtilsService } from '@core/services/utils.service'; -import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; +import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; import { TranslateService } from '@ngx-translate/core'; import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-datasources', templateUrl: './datasources.component.html', - styleUrls: ['./datasources.component.scss', 'widget-config.scss'], + styleUrls: ['./datasources.component.scss', './widget-config.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.html new file mode 100644 index 0000000000..985db7d942 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.html @@ -0,0 +1,42 @@ + +
+
+
timewindow.timewindow
+ + +
+
+ + + {{ 'widget-config.display-timewindow' | translate }} + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts new file mode 100644 index 0000000000..ec7e8d0854 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts @@ -0,0 +1,115 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { widgetType } from '@shared/models/widget.models'; +import { Timewindow } from '@shared/models/time/time.models'; +import { TranslateService } from '@ngx-translate/core'; +import { coerceBoolean } from '@shared/decorators/coercion'; + +export interface TimewindowConfigData { + useDashboardTimewindow: boolean; + displayTimewindow: boolean; + timewindow: Timewindow; +} + +@Component({ + selector: 'tb-timewindow-config-panel', + templateUrl: './timewindow-config-panel.component.html', + styleUrls: ['./widget-config.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => TimewindowConfigPanelComponent), + multi: true + } + ] +}) +export class TimewindowConfigPanelComponent implements ControlValueAccessor, OnInit { + + widgetTypes = widgetType; + + public get widgetType(): widgetType { + return this.widgetConfigComponent.widgetType; + } + + @Input() + disabled: boolean; + + @Input() + @coerceBoolean() + onlyHistoryTimewindow = false; + + + timewindowConfig: UntypedFormGroup; + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder, + public translate: TranslateService, + private widgetConfigComponent: WidgetConfigComponent) { + } + + ngOnInit() { + this.timewindowConfig = this.fb.group({ + useDashboardTimewindow: [null, []], + displayTimewindow: [null, []], + timewindow: [null, []] + }); + this.timewindowConfig.valueChanges.subscribe( + (val) => this.propagateChange(val) + ); + this.timewindowConfig.get('useDashboardTimewindow').valueChanges.subscribe(() => { + this.updateTimewindowConfigEnabledState(); + }); + } + + writeValue(data?: TimewindowConfigData): void { + this.timewindowConfig.patchValue(data || {}, {emitEvent: false}); + this.updateTimewindowConfigEnabledState(); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.timewindowConfig.disable({emitEvent: false}); + } else { + this.timewindowConfig.enable({emitEvent: false}); + this.updateTimewindowConfigEnabledState(); + } + } + + private updateTimewindowConfigEnabledState() { + const useDashboardTimewindow: boolean = this.timewindowConfig.get('useDashboardTimewindow').value; + if (useDashboardTimewindow) { + this.timewindowConfig.get('displayTimewindow').disable({emitEvent: false}); + this.timewindowConfig.get('timewindow').disable({emitEvent: false}); + } else { + this.timewindowConfig.get('displayTimewindow').enable({emitEvent: false}); + this.timewindowConfig.get('timewindow').enable({emitEvent: false}); + } + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts index c5a114d763..186a89537e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts @@ -19,16 +19,17 @@ import { CommonModule } from '@angular/common'; import { SharedModule } from '@app/shared/shared.module'; import { AlarmFilterConfigComponent } from '@home/components/alarm/alarm-filter-config.component'; import { AlarmAssigneeSelectComponent } from '@home/components/alarm/alarm-assignee-select.component'; -import { DataKeysComponent } from '@home/components/widget/data-keys.component'; -import { DataKeyConfigDialogComponent } from '@home/components/widget/data-key-config-dialog.component'; -import { DataKeyConfigComponent } from '@home/components/widget/data-key-config.component'; -import { DatasourceComponent } from '@home/components/widget/datasource.component'; -import { DatasourcesComponent } from '@home/components/widget/datasources.component'; +import { DataKeysComponent } from '@home/components/widget/config/data-keys.component'; +import { DataKeyConfigDialogComponent } from '@home/components/widget/config/data-key-config-dialog.component'; +import { DataKeyConfigComponent } from '@home/components/widget/config/data-key-config.component'; +import { DatasourceComponent } from '@home/components/widget/config/datasource.component'; +import { DatasourcesComponent } from '@home/components/widget/config/datasources.component'; import { EntityAliasSelectComponent } from '@home/components/alias/entity-alias-select.component'; import { FilterSelectComponent } from '@home/components/filter/filter-select.component'; import { WidgetSettingsModule } from '@home/components/widget/lib/settings/widget-settings.module'; -import { WidgetSettingsComponent } from '@home/components/widget/widget-settings.component'; -import { TimewindowConfigPanelComponent } from '@home/components/widget/timewindow-config-panel.component'; +import { WidgetSettingsComponent } from '@home/components/widget/config/widget-settings.component'; +import { TimewindowConfigPanelComponent } from '@home/components/widget/config/timewindow-config-panel.component'; +import { WidgetUnitsComponent } from '@home/components/widget/config/widget-units.component'; @NgModule({ declarations: @@ -43,6 +44,7 @@ import { TimewindowConfigPanelComponent } from '@home/components/widget/timewind EntityAliasSelectComponent, FilterSelectComponent, TimewindowConfigPanelComponent, + WidgetUnitsComponent, WidgetSettingsComponent ], imports: [ @@ -61,6 +63,7 @@ import { TimewindowConfigPanelComponent } from '@home/components/widget/timewind EntityAliasSelectComponent, FilterSelectComponent, TimewindowConfigPanelComponent, + WidgetUnitsComponent, WidgetSettingsComponent ] }) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts index 3d9f60f1ad..39b3c2a741 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts @@ -14,8 +14,8 @@ /// limitations under the License. /// -import { WidgetActionCallbacks } from './action/manage-widget-actions.component.models'; -import { DatasourceCallbacks } from '@home/components/widget/datasource.component.models'; +import { WidgetActionCallbacks } from '@home/components/widget/action/manage-widget-actions.component.models'; +import { DatasourceCallbacks } from '@home/components/widget/config/datasource.component.models'; import { WidgetConfigComponentData } from '@home/models/widget-component.models'; import { Observable } from 'rxjs'; import { AfterViewInit, Directive, EventEmitter, Inject, OnInit } from '@angular/core'; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html new file mode 100644 index 0000000000..d573e65183 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html @@ -0,0 +1,20 @@ + + + + diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.ts new file mode 100644 index 0000000000..4a1665b5b2 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.ts @@ -0,0 +1,67 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, UntypedFormBuilder } from '@angular/forms'; + +@Component({ + selector: 'tb-widget-units', + templateUrl: './widget-units.component.html', + styleUrls: ['./widget-config.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => WidgetUnitsComponent), + multi: true + } + ] +}) +export class WidgetUnitsComponent implements ControlValueAccessor, OnInit { + + @Input() + disabled: boolean; + + unitsFormControl: FormControl; + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder) { + } + + ngOnInit() { + this.unitsFormControl = this.fb.control('', []); + } + + writeValue(units?: string): void { + this.unitsFormControl.patchValue(units, {emitEvent: false}); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.unitsFormControl.disable({emitEvent: false}); + } else { + this.unitsFormControl.enable({emitEvent: false}); + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts index f22828d41d..b9080b93ff 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts @@ -23,7 +23,7 @@ import { AppState } from '@core/core.state'; @Component({ selector: 'tb-simple-card-widget-settings', templateUrl: './simple-card-widget-settings.component.html', - styleUrls: ['../../../widget-config.scss'] + styleUrls: ['../../../config/widget-config.scss'] }) export class SimpleCardWidgetSettingsComponent extends WidgetSettingsComponent { diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts index eb4964de91..e3ff270197 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts @@ -164,7 +164,7 @@ export class WidgetComponentService { (window as any).TbMapWidgetV2 = mod.TbMapWidgetV2; })) ); - widgetModulesTasks.push(from(import('@home/components/widget/trip-animation/trip-animation.component')).pipe( + widgetModulesTasks.push(from(import('@home/components/widget/lib/trip-animation/trip-animation.component')).pipe( tap((mod) => { (window as any).TbTripAnimationWidget = mod.TbTripAnimationWidget; })) diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts index 5368ed2e71..ce2e7055cc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts @@ -29,7 +29,7 @@ import { DateRangeNavigatorWidgetComponent } from '@home/components/widget/lib/date-range-navigator/date-range-navigator.component'; import { MultipleInputWidgetComponent } from '@home/components/widget/lib/multiple-input-widget.component'; -import { TripAnimationComponent } from '@home/components/widget/trip-animation/trip-animation.component'; +import { TripAnimationComponent } from '@home/components/widget/lib/trip-animation/trip-animation.component'; import { PhotoCameraInputWidgetComponent } from '@home/components/widget/lib/photo-camera-input.component'; import { GatewayFormComponent } from '@home/components/widget/lib/gateway/gateway-form.component'; import { NavigationCardsWidgetComponent } from '@home/components/widget/lib/navigation-cards-widget.component'; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html index 86f2cba04e..1766b79009 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html @@ -252,9 +252,9 @@
widget-config.data-settings
widget-config.units
- - - + +
widget-config.decimals
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index 057558f9b8..744747a50a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -82,7 +82,7 @@ import { ToggleHeaderOption } from '@shared/components/toggle-header.component'; import { coerceBoolean } from '@shared/decorators/coercion'; import { basicWidgetConfigComponentsMap } from '@home/components/widget/config/basic/basic-widget-config.module'; import Timeout = NodeJS.Timeout; -import { TimewindowConfigData } from '@home/components/widget/timewindow-config-panel.component'; +import { TimewindowConfigData } from '@home/components/widget/config/timewindow-config-panel.component'; const emptySettingsSchema: JsonSchema = { type: 'object', @@ -96,7 +96,7 @@ const defaultSettingsForm = [ @Component({ selector: 'tb-widget-config', templateUrl: './widget-config.component.html', - styleUrls: ['./widget-config.component.scss', 'widget-config.scss'], + styleUrls: ['./widget-config.component.scss', './config/widget-config.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, 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 fb906561b0..6a1ee20447 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4140,6 +4140,8 @@ "desktop-hide": "Hide widget in desktop mode", "units": "Special symbol to show next to value", "decimals": "Number of digits after floating point", + "units-short": "Units", + "decimals-short": "Decimals", "timewindow": "Timewindow", "use-dashboard-timewindow": "Use dashboard timewindow", "use-widget-timewindow": "Use widget timewindow", From 4dbe1cf0049dde11846ba63a81a59f04129d9c9a Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Mon, 5 Jun 2023 11:13:29 +0300 Subject: [PATCH 123/207] UI: Add support new notification rule Rate limits and improve string items list --- ui-ngx/src/app/modules/common/modules-map.ts | 2 + .../rule-notification-dialog.component.html | 10 ++ .../rule-notification-dialog.component.ts | 11 +- .../string-items-list.component.html | 65 ++++--- .../components/string-items-list.component.ts | 167 +++++++++++++++--- .../app/shared/models/limited-api.models.ts | 43 +++++ .../app/shared/models/notification.models.ts | 7 +- ui-ngx/src/app/shared/models/public-api.ts | 1 + .../assets/locale/locale.constant-en_US.json | 17 +- 9 files changed, 271 insertions(+), 52 deletions(-) create mode 100644 ui-ngx/src/app/shared/models/limited-api.models.ts diff --git a/ui-ngx/src/app/modules/common/modules-map.ts b/ui-ngx/src/app/modules/common/modules-map.ts index 40172e2667..fb6ffb1057 100644 --- a/ui-ngx/src/app/modules/common/modules-map.ts +++ b/ui-ngx/src/app/modules/common/modules-map.ts @@ -177,6 +177,7 @@ import * as CopyButtonComponent from '@shared/components/button/copy-button.comp import * as TogglePasswordComponent from '@shared/components/button/toggle-password.component'; import * as ProtobufContentComponent from '@shared/components/protobuf-content.component'; import * as SlackConversationAutocompleteComponent from '@shared/components/slack-conversation-autocomplete.component'; +import * as StringItemsListComponent from '@shared/components/string-items-list.component'; import * as AddEntityDialogComponent from '@home/components/entity/add-entity-dialog.component'; import * as EntitiesTableComponent from '@home/components/entity/entities-table.component'; @@ -472,6 +473,7 @@ class ModulesMap implements IModulesMap { '@shared/components/button/toggle-password.component': TogglePasswordComponent, '@shared/components/protobuf-content.component': ProtobufContentComponent, '@shared/components/slack-conversation-autocomplete.component': SlackConversationAutocompleteComponent, + '@shared/components/string-items-list.component': StringItemsListComponent, '@home/components/entity/add-entity-dialog.component': AddEntityDialogComponent, '@home/components/entity/entities-table.component': EntitiesTableComponent, diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html index 0cf94e0292..d8e5f8ce31 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html @@ -499,6 +499,16 @@ {{ 'notification.rate-limits-trigger-settings' | translate }} +
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts index 985f121432..eb156cd071 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts @@ -66,6 +66,8 @@ import { ApiUsageStateValue, ApiUsageStateValueTranslationMap } from '@shared/models/api-usage.models'; +import { LimitedApi, LimitedApiTranslationMap } from '@shared/models/limited-api.models'; +import { StringItemsOption } from '@shared/components/string-items-list.component'; export interface RuleNotificationDialogData { rule?: NotificationRule; @@ -130,6 +132,8 @@ export class RuleNotificationDialogComponent extends apiFeatures: ApiFeature[] = Object.values(ApiFeature); apiFeatureTranslationMap = ApiFeatureTranslationMap; + limitedApis: StringItemsOption[]; + entityType = EntityType; isAdd = true; @@ -172,6 +176,11 @@ export class RuleNotificationDialogComponent extends this.isAdd = data.isAdd; } + this.limitedApis = Object.values(LimitedApi).map(value => ({ + name: this.translate.instant(LimitedApiTranslationMap.get(value)), + value + })); + this.stepperOrientation = this.breakpointObserver.observe(MediaBreakpoints['gt-xs']) .pipe(map(({matches}) => matches ? 'horizontal' : 'vertical')); @@ -305,7 +314,7 @@ export class RuleNotificationDialogComponent extends this.rateLimitsTemplateForm = this.fb.group({ triggerConfig: this.fb.group({ - + apis: [] }) }); diff --git a/ui-ngx/src/app/shared/components/string-items-list.component.html b/ui-ngx/src/app/shared/components/string-items-list.component.html index f1f9f0d118..4677cbc3de 100644 --- a/ui-ngx/src/app/shared/components/string-items-list.component.html +++ b/ui-ngx/src/app/shared/components/string-items-list.component.html @@ -15,24 +15,47 @@ limitations under the License. --> -
- - {{ label }} - - - {{item}} - close - - - - {{ hint }} - {{ requiredText }} - -
+ + {{ label }} + + + {{ item.name }} + close + + + + + + + + + {{ 'common.not-found' | translate }} + + + {{ hint }} + + {{ requiredText }} + + diff --git a/ui-ngx/src/app/shared/components/string-items-list.component.ts b/ui-ngx/src/app/shared/components/string-items-list.component.ts index 0febd3cad4..274f12fd3a 100644 --- a/ui-ngx/src/app/shared/components/string-items-list.component.ts +++ b/ui-ngx/src/app/shared/components/string-items-list.component.ts @@ -14,13 +14,27 @@ /// limitations under the License. /// -import { Component, forwardRef, Input } from '@angular/core'; -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; +import { + AbstractControl, + ControlValueAccessor, + FormBuilder, + FormGroup, + NG_VALUE_ACCESSOR, + Validators +} from '@angular/forms'; import { MatChipInputEvent } from '@angular/material/chips'; import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes'; import { FloatLabelType, MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field'; -import { coerceBoolean } from '@shared/decorators/coercion'; +import { coerceArray, coerceBoolean } from '@shared/decorators/coercion'; +import { Observable, of } from 'rxjs'; +import { filter, mergeMap, share, tap } from 'rxjs/operators'; +import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; +export interface StringItemsOption { + name: string; + value: any; +} @Component({ selector: 'tb-string-items-list', templateUrl: './string-items-list.component.html', @@ -33,17 +47,29 @@ import { coerceBoolean } from '@shared/decorators/coercion'; } ] }) -export class StringItemsListComponent implements ControlValueAccessor{ +export class StringItemsListComponent implements ControlValueAccessor, OnInit { stringItemsForm: FormGroup; + + filteredValues: Observable>; + + searchText = ''; + + itemList: StringItemsOption[] = []; + private modelValue: Array | null; readonly separatorKeysCodes: number[] = [ENTER, COMMA, SEMICOLON]; + @ViewChild('stringItemInput', {static: true}) stringItemInput: ElementRef; + @ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger; + private requiredValue: boolean; + get required(): boolean { return this.requiredValue; } + @Input() @coerceBoolean() set required(value: boolean) { @@ -80,19 +106,52 @@ export class StringItemsListComponent implements ControlValueAccessor{ editable = false; @Input() - subscriptSizing: SubscriptSizing = 'fixed' + subscriptSizing: SubscriptSizing = 'fixed'; - private propagateChange = (v: any) => { }; + @Input() + @coerceArray() + predefinedValues: StringItemsOption[]; + + get itemsControl(): AbstractControl { + return this.stringItemsForm.get('items'); + } + + get itemControl(): AbstractControl { + return this.stringItemsForm.get('item'); + } + + private propagateChange = (v: any) => { + }; + private dirty = false; constructor(private fb: FormBuilder) { this.stringItemsForm = this.fb.group({ - items: [null, this.required ? [Validators.required] : []] + item: [null], + items: [null] }); } + ngOnInit() { + if (this.predefinedValues) { + this.filteredValues = this.itemControl.valueChanges + .pipe( + tap((value) => { + if (value && typeof value !== 'string') { + this.add(value); + } else if (value === null) { + this.clear(); + } + }), + filter((value) => typeof value === 'string'), + mergeMap(name => this.fetchValues(name)), + share() + ); + } + } + updateValidators() { - this.stringItemsForm.get('items').setValidators(this.required ? [Validators.required] : []); - this.stringItemsForm.get('items').updateValueAndValidity(); + this.itemsControl.setValidators(this.required ? [Validators.required] : []); + this.itemsControl.updateValueAndValidity(); } registerOnChange(fn: any): void { @@ -112,48 +171,100 @@ export class StringItemsListComponent implements ControlValueAccessor{ } writeValue(value: Array | null): void { + this.searchText = ''; if (value != null && value.length > 0) { this.modelValue = [...value]; - this.stringItemsForm.get('items').setValue(value); + this.itemList = []; + if (this.predefinedValues) { + value.forEach(item => { + const findItem = this.predefinedValues.find(option => option.value === item); + if (findItem) { + this.itemList.push(findItem); + } + }); + } else { + value.forEach(item => this.itemList.push({value: item, name: item})); + } + this.itemsControl.setValue(this.itemList, {emitEvents: false}); } else { - this.stringItemsForm.get('items').setValue(null); + this.itemsControl.setValue(null, {emitEvents: false}); this.modelValue = null; + this.itemList = []; } + this.dirty = true; } addItem(event: MatChipInputEvent): void { - let item = event.value || ''; - const input = event.chipInput.inputElement; - item = item.trim(); + const item = event.value?.trim() ?? ''; if (item) { - if (!this.modelValue || this.modelValue.indexOf(item) === -1) { - if (!this.modelValue) { - this.modelValue = []; + if (this.predefinedValues) { + const findItems = this.predefinedValues + .filter(value => value.name.toLowerCase().includes(item.toLowerCase())); + if (findItems.length === 1) { + this.add(findItems[0]); } - this.modelValue.push(item); - this.stringItemsForm.get('items').setValue(this.modelValue); - } - this.propagateChange(this.modelValue); - if (input) { - input.value = ''; + } else { + this.add({value: item, name: item}); } } } - removeItems(item: string) { - const index = this.modelValue.indexOf(item); + removeItems(item: StringItemsOption) { + const index = this.modelValue.indexOf(item.value); if (index >= 0) { this.modelValue.splice(index, 1); + this.itemList.splice(index, 1); if (!this.modelValue.length) { this.modelValue = null; } - this.stringItemsForm.get('items').setValue(this.modelValue); + this.itemsControl.setValue(this.itemList); this.propagateChange(this.modelValue); + this.autocomplete?.closePanel(); + } + } + + onFocus() { + if (this.dirty) { + this.itemControl.updateValueAndValidity({onlySelf: true, emitEvent: true}); + this.dirty = false; + } + } + + displayValueFn(values?: StringItemsOption): string | undefined { + return values ? values.name : undefined; + } + + private add(item: StringItemsOption) { + if (!this.modelValue || this.modelValue.indexOf(item.value) === -1) { + if (!this.modelValue) { + this.modelValue = []; + } + this.modelValue.push(item.value); + this.itemList.push(item); + this.itemsControl.setValue(this.itemList); } + this.propagateChange(this.modelValue); + this.clear(); } - get stringItemsList(): string[] { - return this.stringItemsForm.get('items').value; + private fetchValues(searchText?: string): Observable> { + if (!this.predefinedValues?.length) { + return of([]); + } + this.searchText = searchText; + let result = this.predefinedValues; + if (searchText && searchText.length) { + result = this.predefinedValues.filter(option => option.name.toLowerCase().includes(searchText.toLowerCase())); + } + return of(result); } + private clear(value: string = '') { + this.stringItemInput.nativeElement.value = value; + this.itemControl.patchValue(value, {emitEvent: true}); + setTimeout(() => { + this.stringItemInput.nativeElement.blur(); + this.stringItemInput.nativeElement.focus(); + }, 0); + } } diff --git a/ui-ngx/src/app/shared/models/limited-api.models.ts b/ui-ngx/src/app/shared/models/limited-api.models.ts new file mode 100644 index 0000000000..3b68800f24 --- /dev/null +++ b/ui-ngx/src/app/shared/models/limited-api.models.ts @@ -0,0 +1,43 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +export enum LimitedApi { + ENTITY_EXPORT = 'ENTITY_EXPORT', + ENTITY_IMPORT = 'ENTITY_IMPORT', + NOTIFICATION_REQUESTS = 'NOTIFICATION_REQUESTS', + NOTIFICATION_REQUESTS_PER_RULE = 'NOTIFICATION_REQUESTS_PER_RULE', + REST_REQUESTS_PER_TENANT = 'REST_REQUESTS_PER_TENANT', + REST_REQUESTS_PER_CUSTOMER = 'REST_REQUESTS_PER_CUSTOMER', + WS_UPDATES_PER_SESSION = 'WS_UPDATES_PER_SESSION', + CASSANDRA_QUERIES = 'CASSANDRA_QUERIES', + TRANSPORT_MESSAGES_PER_TENANT = 'TRANSPORT_MESSAGES_PER_TENANT', + TRANSPORT_MESSAGES_PER_DEVICE = 'TRANSPORT_MESSAGES_PER_DEVICE' +} + +export const LimitedApiTranslationMap = new Map( + [ + [LimitedApi.ENTITY_EXPORT, 'api-limit.entity-version-creation'], + [LimitedApi.ENTITY_IMPORT, 'api-limit.entity-version-load'], + [LimitedApi.NOTIFICATION_REQUESTS, 'api-limit.notification-requests'], + [LimitedApi.NOTIFICATION_REQUESTS_PER_RULE, 'api-limit.notification-requests-per-rule'], + [LimitedApi.REST_REQUESTS_PER_TENANT, 'api-limit.rest-api-requests'], + [LimitedApi.REST_REQUESTS_PER_CUSTOMER, 'api-limit.rest-api-requests-per-customer'], + [LimitedApi.WS_UPDATES_PER_SESSION, 'api-limit.ws-updates-per-session'], + [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'] + ] +); diff --git a/ui-ngx/src/app/shared/models/notification.models.ts b/ui-ngx/src/app/shared/models/notification.models.ts index 48902231ca..2cef7c6cc2 100644 --- a/ui-ngx/src/app/shared/models/notification.models.ts +++ b/ui-ngx/src/app/shared/models/notification.models.ts @@ -26,6 +26,7 @@ import { NotificationRuleId } from '@shared/models/id/notification-rule-id'; import { AlarmSearchStatus, AlarmSeverity, AlarmStatus } from '@shared/models/alarm.models'; import { EntityType } from '@shared/models/entity-type.models'; import { ApiFeature, ApiUsageStateValue } from '@shared/models/api-usage.models'; +import { LimitedApi } from '@shared/models/limited-api.models'; export interface Notification { readonly id: NotificationId; @@ -119,7 +120,7 @@ export interface NotificationRule extends Omit, 'la export type NotificationRuleTriggerConfig = Partial; + ApiUsageLimitNotificationRuleTriggerConfig & RateLimitsNotificationRuleTriggerConfig>; export interface AlarmNotificationRuleTriggerConfig { alarmTypes?: Array; @@ -178,6 +179,10 @@ export interface ApiUsageLimitNotificationRuleTriggerConfig { notifyOn: ApiUsageStateValue[]; } +export interface RateLimitsNotificationRuleTriggerConfig { + apis: LimitedApi[]; +} + export enum ComponentLifecycleEvent { STARTED = 'STARTED', UPDATED = 'UPDATED', diff --git a/ui-ngx/src/app/shared/models/public-api.ts b/ui-ngx/src/app/shared/models/public-api.ts index dbc5e11213..aa93bece92 100644 --- a/ui-ngx/src/app/shared/models/public-api.ts +++ b/ui-ngx/src/app/shared/models/public-api.ts @@ -37,6 +37,7 @@ export * from './entity-type.models'; export * from './entity-view.models'; export * from './error.models'; export * from './event.models'; +export * from './limited-api.models'; export * from './login.models'; export * from './material.models'; export * from './notification.models'; 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 1c20dbe740..056cd2c396 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -756,6 +756,18 @@ "view-details": "View details", "view-statistics": "View statistics" }, + "api-limit": { + "cassandra-queries": "Cassandra queries", + "entity-version-creation": "Entity version creation", + "entity-version-load": "Entity version load", + "notification-requests": "Notification requests", + "notification-requests-per-rule": "Notification requests per rule", + "rest-api-requests": "REST API requests", + "rest-api-requests-per-customer": "REST API requests per customer", + "transport-messages": "Transport messages", + "transport-messages-per-device": "Transport messages per device", + "ws-updates-per-session": "WS updates per session" + }, "audit-log": { "audit": "Audit", "audit-logs": "Audit Logs", @@ -839,7 +851,8 @@ "created-time": "Created time", "loading": "Loading...", "proceed": "Proceed", - "open-details-page": "Open details page" + "open-details-page": "Open details page", + "not-found": "Not found" }, "content-type": { "json": "Json", @@ -2936,6 +2949,8 @@ "only-rule-chain-lifecycle-failures": "Only rule chain lifecycle failures", "only-rule-node-lifecycle-failures": "Only rule node lifecycle failures", "platform-users": "Platform users", + "rate-limits": "Rate limits", + "rate-limits-hint": "If the field is empty, the trigger will be applied to all rate limits", "recipient": "Recipient", "recipient-group": "Recipient group", "recipient-type": { From 72423991b9f9b96c0f8bd332ab7874953b936549 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Mon, 5 Jun 2023 13:14:44 +0300 Subject: [PATCH 124/207] Add option compatibility for DockerComposeContainer to work locally with docker compose --- .../server/msa/ContainerTestSuite.java | 1 + .../server/msa/ThingsBoardDbInstaller.java | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java index c6be6ec271..95b1b2129e 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java @@ -156,6 +156,7 @@ public class ContainerTestSuite { testContainer = new DockerComposeContainerImpl<>(composeFiles) .withPull(false) .withLocalCompose(true) + .withOptions("--compatibility") .withTailChildContainers(!skipTailChildContainers) .withEnv(installTb.getEnv()) .withEnv(queueEnv) diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java index 40f9758f33..ea3c9c637a 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java @@ -68,6 +68,7 @@ public class ThingsBoardDbInstaller { public ThingsBoardDbInstaller() { log.info("System property of blackBoxTests.redisCluster is {}", IS_REDIS_CLUSTER); + log.info("System property of blackBoxTests.redisCluster is {}", IS_REDIS_SENTINEL); log.info("System property of blackBoxTests.hybridMode is {}", IS_HYBRID_MODE); List composeFiles = new ArrayList<>(Arrays.asList( new File("./../../docker/docker-compose.yml"), @@ -240,13 +241,22 @@ public class ThingsBoardDbInstaller { dockerCompose.withCommand("volume rm -f " + postgresDataVolume + " " + tbLogVolume + " " + tbCoapTransportLogVolume + " " + tbLwm2mTransportLogVolume + " " + tbHttpTransportLogVolume + - " " + tbMqttTransportLogVolume + " " + tbSnmpTransportLogVolume + " " + tbVcExecutorLogVolume + - (IS_REDIS_CLUSTER - ? IntStream.range(0, 6).mapToObj(i -> " " + redisClusterDataVolume + '-' + i).collect(Collectors.joining()) - : redisDataVolume)); + " " + tbMqttTransportLogVolume + " " + tbSnmpTransportLogVolume + " " + tbVcExecutorLogVolume + resolveComposeVolumeLog()); dockerCompose.invokeDocker(); } + private String resolveComposeVolumeLog() { + if (IS_REDIS_CLUSTER) { + return IntStream.range(0, 6).mapToObj(i -> " " + redisClusterDataVolume + "-" + i).collect(Collectors.joining()); + } + if (IS_REDIS_SENTINEL) { + return redisSentinelDataVolume + "-" + "master " + " " + + redisSentinelDataVolume + "-" + "slave" + " " + + redisSentinelDataVolume + " " + "sentinel"; + } + return redisDataVolume; + } + private void copyLogs(String volumeName, String targetDir) { File tbLogsDir = new File(targetDir); tbLogsDir.mkdirs(); From 90bf0a0ace65f4d32eaf3d4007bc6fae80ce5a66 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Mon, 5 Jun 2023 13:39:06 +0300 Subject: [PATCH 125/207] Rewrite readme for redis sentinel --- docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/README.md b/docker/README.md index 437e583a99..1a852c80eb 100644 --- a/docker/README.md +++ b/docker/README.md @@ -21,7 +21,7 @@ In order to set cache type change the value of `CACHE` variable in `.env` file t - `redis` - use Redis standalone cache (1 node - 1 master); - `redis-cluster` - use Redis cluster cache (6 nodes - 3 masters, 3 slaves); -- `redis-sentinel` - use Redis cluster in a sentinel mode (3 nodes - 1 master, 1 slave, 1 sentinel) +- `redis-sentinel` - use Redis sentinel cache (3 nodes - 1 master, 1 slave, 1 sentinel) **NOTE**: According to the cache type corresponding docker service will be deployed (see `docker-compose.redis.yml`, `docker-compose.redis-cluster.yml`, `docker-compose.redis-sentinel.yml` for details). From 86c8ee6bdedca0808dce3fae20462cf2e4a932b4 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Mon, 5 Jun 2023 15:05:01 +0300 Subject: [PATCH 126/207] UI: Refactoring and add support edge rule chains --- .../rulechain/rulechain-page.component.html | 1 + .../rulechain/rulechain-page.component.ts | 18 ++++++++- .../rule-chain-select.component.html | 1 + .../rule-chain-select.component.scss | 14 +------ .../rule-chain/rule-chain-select.component.ts | 39 +++++++------------ 5 files changed, 33 insertions(+), 40 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html index b4b00546df..4cdaed942d 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html @@ -32,6 +32,7 @@ diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts index 46ce1978dc..c1f23b5714 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.ts @@ -15,7 +15,9 @@ /// import { + AfterViewChecked, AfterViewInit, + ChangeDetectorRef, Component, ElementRef, EventEmitter, @@ -90,6 +92,7 @@ import { MatMiniFabButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { VersionControlComponent } from '@home/components/vc/version-control.component'; import { ComponentClusteringMode } from '@shared/models/component-descriptor.models'; +import { MatDrawer } from '@angular/material/sidenav'; import Timeout = NodeJS.Timeout; @Component({ @@ -99,7 +102,7 @@ import Timeout = NodeJS.Timeout; encapsulation: ViewEncapsulation.None }) export class RuleChainPageComponent extends PageComponent - implements AfterViewInit, OnInit, OnDestroy, HasDirtyFlag, ISearchableComponent { + implements AfterViewInit, OnInit, OnDestroy, HasDirtyFlag, ISearchableComponent, AfterViewChecked { get isDirty(): boolean { return this.isDirtyValue || this.isImport; @@ -121,6 +124,8 @@ export class RuleChainPageComponent extends PageComponent @ViewChild('ruleChainMenuTrigger', {static: true}) ruleChainMenuTrigger: MatMenuTrigger; + @ViewChild('drawer') drawer: MatDrawer; + eventTypes = EventType; debugEventTypes = DebugEventType; @@ -265,6 +270,7 @@ export class RuleChainPageComponent extends PageComponent private popoverService: TbPopoverService, private renderer: Renderer2, private viewContainerRef: ViewContainerRef, + private changeDetector: ChangeDetectorRef, public dialog: MatDialog, public dialogService: DialogService, public fb: UntypedFormBuilder) { @@ -280,6 +286,10 @@ export class RuleChainPageComponent extends PageComponent ngOnInit() { } + ngAfterViewChecked(){ + this.changeDetector.detectChanges(); + } + ngAfterViewInit() { fromEvent(this.ruleNodeSearchInputField.nativeElement, 'keyup') .pipe( @@ -299,7 +309,11 @@ export class RuleChainPageComponent extends PageComponent } currentRuleChainIdChanged(ruleChainId: string) { - this.router.navigateByUrl(`ruleChains/${ruleChainId}`); + if (this.ruleChainType === RuleChainType.CORE) { + this.router.navigateByUrl(`ruleChains/${ruleChainId}`); + } else { + this.router.navigateByUrl(`edgeManagement/ruleChains/${ruleChainId}`); + } } onSearchTextUpdated(searchText: string) { diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html index 8d3be71f79..2b9c227c30 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html @@ -16,6 +16,7 @@ --> >; ruleChainId: string | null; - @ViewChild('ruleChainSelectPanelOrigin') ruleChainSelectPanelOrigin: CdkOverlayOrigin; - private propagateChange = (v: any) => { }; constructor(private store: Store, - private ruleChainService: RuleChainService, - private overlay: Overlay, - private breakpointObserver: BreakpointObserver, - private viewContainerRef: ViewContainerRef, - private nativeElement: ElementRef, - @Inject(DOCUMENT) private document: Document, - @Inject(WINDOW) private window: Window) { - } - - registerOnChange(fn: any): void { - this.propagateChange = fn; - } - - registerOnTouched(fn: any): void { + private ruleChainService: RuleChainService) { } ngOnInit() { - const pageLink = new PageLink(100, 0, null, { property: 'name', direction: Direction.ASC @@ -96,6 +77,14 @@ export class RuleChainSelectComponent implements ControlValueAccessor, OnInit { ); } + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } @@ -115,7 +104,7 @@ export class RuleChainSelectComponent implements ControlValueAccessor, OnInit { } private getRuleChains(pageLink: PageLink): Observable> { - return this.ruleChainService.getRuleChains(pageLink, RuleChainType.CORE, {ignoreLoading: true}); + return this.ruleChainService.getRuleChains(pageLink, this.ruleChainType, {ignoreLoading: true}); } } From 1f6e0e82713d86488ed2205187ac02b17107430f Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Mon, 5 Jun 2023 15:26:48 +0300 Subject: [PATCH 127/207] UI: Refactoring --- .../components/rule-chain/rule-chain-select.component.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.ts b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.ts index 7e4efb7402..003d85b751 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.ts +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.ts @@ -61,8 +61,7 @@ export class RuleChainSelectComponent implements ControlValueAccessor, OnInit { private propagateChange = (v: any) => { }; - constructor(private store: Store, - private ruleChainService: RuleChainService) { + constructor(private ruleChainService: RuleChainService) { } ngOnInit() { From 4065c94131165ded41d38eccc43c4ec6fd1ede64 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Mon, 5 Jun 2023 17:15:32 +0300 Subject: [PATCH 128/207] Refactor naming to resolve redis compose in black-box tests --- .../thingsboard/server/msa/ContainerTestSuite.java | 8 ++++---- .../server/msa/ThingsBoardDbInstaller.java | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java index 95b1b2129e..dd3948c495 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java @@ -111,8 +111,8 @@ public class ContainerTestSuite { new File(targetDir + (IS_HYBRID_MODE ? "docker-compose.hybrid-test-extras.yml" : "docker-compose.postgres-test-extras.yml")), new File(targetDir + "docker-compose.postgres.volumes.yml"), new File(targetDir + "docker-compose." + QUEUE_TYPE + ".yml"), - new File(targetDir + resolveComposeFile()), - new File(targetDir + resolveComposeVolumesFile()), + new File(targetDir + resolveRedisComposeFile()), + new File(targetDir + resolveRedisComposeVolumesFile()), new File(targetDir + ("docker-selenium.yml")) )); @@ -179,7 +179,7 @@ public class ContainerTestSuite { } } - private static String resolveComposeFile() { + private static String resolveRedisComposeFile() { if (IS_REDIS_CLUSTER) { return "docker-compose.redis-cluster.yml"; } @@ -189,7 +189,7 @@ public class ContainerTestSuite { return "docker-compose.redis.yml"; } - private static String resolveComposeVolumesFile() { + private static String resolveRedisComposeVolumesFile() { if (IS_REDIS_CLUSTER) { return "docker-compose.redis-cluster.volumes.yml"; } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java index ea3c9c637a..e41bbc3449 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java @@ -77,8 +77,8 @@ public class ThingsBoardDbInstaller { ? new File("./../../docker/docker-compose.hybrid.yml") : new File("./../../docker/docker-compose.postgres.yml"), new File("./../../docker/docker-compose.postgres.volumes.yml"), - resolveComposeFile(), - resolveComposeVolumesFile() + resolveRedisComposeFile(), + resolveRedisComposeVolumesFile() )); if (IS_HYBRID_MODE) { composeFiles.add(new File("./../../docker/docker-compose.cassandra.volumes.yml")); @@ -132,7 +132,7 @@ public class ThingsBoardDbInstaller { dockerCompose.withEnv(env); } - private static File resolveComposeVolumesFile() { + private static File resolveRedisComposeVolumesFile() { if (IS_REDIS_CLUSTER) { return new File("./../../docker/docker-compose.redis-cluster.volumes.yml"); } @@ -142,7 +142,7 @@ public class ThingsBoardDbInstaller { return new File("./../../docker/docker-compose.redis.volumes.yml"); } - private static File resolveComposeFile() { + private static File resolveRedisComposeFile() { if (IS_REDIS_CLUSTER) { return new File("./../../docker/docker-compose.redis-cluster.yml"); } @@ -241,11 +241,11 @@ public class ThingsBoardDbInstaller { dockerCompose.withCommand("volume rm -f " + postgresDataVolume + " " + tbLogVolume + " " + tbCoapTransportLogVolume + " " + tbLwm2mTransportLogVolume + " " + tbHttpTransportLogVolume + - " " + tbMqttTransportLogVolume + " " + tbSnmpTransportLogVolume + " " + tbVcExecutorLogVolume + resolveComposeVolumeLog()); + " " + tbMqttTransportLogVolume + " " + tbSnmpTransportLogVolume + " " + tbVcExecutorLogVolume + resolveRedisComposeVolumeLog()); dockerCompose.invokeDocker(); } - private String resolveComposeVolumeLog() { + private String resolveRedisComposeVolumeLog() { if (IS_REDIS_CLUSTER) { return IntStream.range(0, 6).mapToObj(i -> " " + redisClusterDataVolume + "-" + i).collect(Collectors.joining()); } From c71d29c5075c6322e40e9752dde6a02582bedc3d Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 5 Jun 2023 19:52:34 +0300 Subject: [PATCH 129/207] UI: Entities table basic widget config. --- .../basic/basic-widget-config.module.ts | 18 +- ...entities-table-basic-config.component.html | 62 +++ .../entities-table-basic-config.component.ts | 107 +++++ .../basic/common/data-key-row.component.html | 155 ++++++++ .../basic/common/data-key-row.component.scss | 45 +++ .../basic/common/data-key-row.component.ts | 365 ++++++++++++++++++ .../common/data-keys-panel.component.html | 66 ++++ .../common/data-keys-panel.component.scss | 71 ++++ .../basic/common/data-keys-panel.component.ts | 234 +++++++++++ .../widget/config/data-keys.component.scss | 144 +++---- .../widget/config/datasource.component.html | 2 +- .../widget/config/datasource.component.ts | 4 + .../widget/config/datasources.component.ts | 4 + .../widget/config/widget-config.scss | 94 ++--- .../assets/locale/locale.constant-en_US.json | 7 +- 15 files changed, 1257 insertions(+), 121 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index e7d0d58b13..73ebfb37c7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -25,11 +25,19 @@ import { import { WidgetActionsPanelComponent } from '@home/components/widget/config/basic/common/widget-actions-panel.component'; +import { + EntitiesTableBasicConfigComponent +} from '@home/components/widget/config/basic/cards/entities-table-basic-config.component'; +import { DataKeysPanelComponent } from '@home/components/widget/config/basic/common/data-keys-panel.component'; +import { DataKeyRowComponent } from '@home/components/widget/config/basic/common/data-key-row.component'; @NgModule({ declarations: [ WidgetActionsPanelComponent, - SimpleCardBasicConfigComponent + SimpleCardBasicConfigComponent, + EntitiesTableBasicConfigComponent, + DataKeyRowComponent, + DataKeysPanelComponent ], imports: [ CommonModule, @@ -38,12 +46,16 @@ import { ], exports: [ WidgetActionsPanelComponent, - SimpleCardBasicConfigComponent + SimpleCardBasicConfigComponent, + EntitiesTableBasicConfigComponent, + DataKeyRowComponent, + DataKeysPanelComponent ] }) export class BasicWidgetConfigModule { } export const basicWidgetConfigComponentsMap: {[key: string]: Type} = { - 'tb-simple-card-basic-config': SimpleCardBasicConfigComponent + 'tb-simple-card-basic-config': SimpleCardBasicConfigComponent, + 'tb-entities-table-basic-config': EntitiesTableBasicConfigComponent }; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html new file mode 100644 index 0000000000..ed73853ad9 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html @@ -0,0 +1,62 @@ + + + + + + + + +
+
widget-config.appearance
+
+
{{ 'widget-config.text-color' | translate }}
+
+ + + +
+
+
+
{{ 'widget-config.background' | translate }}
+
+ + + +
+
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts new file mode 100644 index 0000000000..6ec1d6c5c4 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts @@ -0,0 +1,107 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { + DataKey, + Datasource, + datasourcesHasAggregation, + datasourcesHasOnlyComparisonAggregation +} from '@shared/models/widget.models'; + +@Component({ + selector: 'tb-entities-table-basic-config', + templateUrl: './entities-table-basic-config.component.html', + styleUrls: ['../basic-config.scss', '../../widget-config.scss'] +}) +export class EntitiesTableBasicConfigComponent extends BasicWidgetConfigComponent { + + public get displayTimewindowConfig(): boolean { + const datasources = this.entitiesTableWidgetConfigForm.get('datasources').value; + return datasourcesHasAggregation(datasources); + } + + public onlyHistoryTimewindow(): boolean { + const datasources = this.entitiesTableWidgetConfigForm.get('datasources').value; + return datasourcesHasOnlyComparisonAggregation(datasources); + } + + public get datasource(): Datasource { + const datasources: Datasource[] = this.entitiesTableWidgetConfigForm.get('datasources').value; + if (datasources && datasources.length) { + return datasources[0]; + } else { + return null; + } + } + + entitiesTableWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + private fb: UntypedFormBuilder) { + super(store); + } + + protected configForm(): UntypedFormGroup { + return this.entitiesTableWidgetConfigForm; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + this.entitiesTableWidgetConfigForm = this.fb.group({ + timewindowConfig: [{ + useDashboardTimewindow: configData.config.useDashboardTimewindow, + displayTimewindow: configData.config.useDashboardTimewindow, + timewindow: configData.config.timewindow + }, []], + datasources: [configData.config.datasources, []], + columns: [this.getColumns(configData.config.datasources), []], + color: [configData.config.color, []], + backgroundColor: [configData.config.backgroundColor, []], + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + this.widgetConfig.config.useDashboardTimewindow = config.timewindowConfig.useDashboardTimewindow; + this.widgetConfig.config.displayTimewindow = config.timewindowConfig.displayTimewindow; + this.widgetConfig.config.timewindow = config.timewindowConfig.timewindow; + this.widgetConfig.config.datasources = config.datasources; + this.setColumns(config.columns, this.widgetConfig.config.datasources); + this.widgetConfig.config.actions = config.actions; + this.widgetConfig.config.color = config.color; + this.widgetConfig.config.backgroundColor = config.backgroundColor; + return this.widgetConfig; + } + + private getColumns(datasources?: Datasource[]): DataKey[] { + if (datasources && datasources.length) { + return datasources[0].dataKeys || []; + } + return []; + } + + private setColumns(columns: DataKey[], datasources?: Datasource[]) { + if (datasources && datasources.length) { + datasources[0].dataKeys = columns; + } + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html new file mode 100644 index 0000000000..cf7b380650 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html @@ -0,0 +1,155 @@ + +
+ + + +
+
+
+ + notifications + + + timeline + +
+
+ + + +
+
+ + +
+
+ +
+ + + + + notifications + + + timeline + + + + + +
+
+ entity.no-keys-found +
+ + + {{ translate.get('entity.no-key-matching', + {key: truncate.transform(keySearchText, true, 6, '...')}) | async }} + + + entity.create-new-key + + + {{'entity.create-new-key' | translate }} + notifications + + + timeline + + +
+
+
+
+ + + +
+ + + f() + + + + + + + + {{ modelValue?.aggregationType }}({{ modelValue?.name }}) + + + {{modelValue?.name}} + + diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss new file mode 100644 index 0000000000..a7165af95a --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-data-key-row { + height: 38px; + display: flex; + flex-direction: row; + gap: 12px; + padding-left: 12px; + + .mat-mdc-form-field.tb-inline-field.tb-key-field { + .mat-mdc-text-field-wrapper:not(.mdc-text-field--outlined) { + .mat-mdc-form-field-infix { + padding-top: 0; + padding-bottom: 6px; + .mdc-evolution-chip-set .mdc-evolution-chip { + margin: 0; + } + input.mat-mdc-chip-input { + height: 32px; + margin-left: 0; + } + } + } + .mat-mdc-chip.mat-mdc-standard-chip.tb-datakey-chip { + .tb-attribute-chip { + .tb-chip-labels { + background: transparent; + } + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts new file mode 100644 index 0000000000..5664ec8d29 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts @@ -0,0 +1,365 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { + ChangeDetectorRef, + Component, + ElementRef, + forwardRef, + Input, + OnChanges, + OnInit, + SimpleChanges, + ViewChild, + ViewEncapsulation +} from '@angular/core'; +import { + AbstractControl, + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + ValidationErrors +} from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKey, DatasourceType, JsonSettingsSchema, widgetType } from '@shared/models/widget.models'; +import { DataKeysPanelComponent } from '@home/components/widget/config/basic/common/data-keys-panel.component'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { AggregationType } from '@shared/models/time/time.models'; +import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes'; +import { MatChipGrid, MatChipInputEvent } from '@angular/material/chips'; +import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; +import { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete'; +import { Observable, of } from 'rxjs'; +import { filter, map, mergeMap, publishReplay, refCount, share, tap } from 'rxjs/operators'; +import { TranslateService } from '@ngx-translate/core'; +import { TruncatePipe } from '@shared/pipe/truncate.pipe'; + +export const dataKeyRowValidator = (control: AbstractControl): ValidationErrors | null => { + const dataKey: DataKey = control.value; + if (!dataKey || !dataKey.type || !dataKey.name) { + return { + dataKey: true + }; + } + return null; +}; + +@Component({ + selector: 'tb-data-key-row', + templateUrl: './data-key-row.component.html', + styleUrls: ['./data-key-row.component.scss', '../../data-keys.component.scss', '../../widget-config.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => DataKeyRowComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChanges { + + dataKeyTypes = DataKeyType; + widgetTypes = widgetType; + + separatorKeysCodes: number[] = [ENTER, COMMA, SEMICOLON]; + + @ViewChild('keyInput') keyInput: ElementRef; + @ViewChild('keyAutocomplete') matAutocomplete: MatAutocomplete; + @ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger; + @ViewChild('chipList') chipList: MatChipGrid; + + @Input() + disabled: boolean; + + @Input() + datasourceType: DatasourceType; + + @Input() + entityAliasId: string; + + @Input() + deviceId: string; + + keyFormControl: UntypedFormControl; + + keyRowFormGroup: UntypedFormGroup; + + modelValue: DataKey; + + filteredKeys: Observable>; + + keySearchText = ''; + + private latestKeySearchTextResult: Array = null; + private keyFetchObservable$: Observable> = null; + + get dataKeyType(): DataKeyType { + return this.dataKeysPanelComponent.dataKeyType; + } + + get alarmKeys(): Array { + return this.dataKeysPanelComponent.alarmKeys; + } + + get functionTypeKeys(): Array { + return this.dataKeysPanelComponent.functionTypeKeys; + } + + get widgetType(): widgetType { + return this.widgetConfigComponent.widgetType; + } + + get callbacks(): DataKeysCallbacks { + return this.widgetConfigComponent.widgetConfigCallbacks; + } + + get datakeySettingsSchema(): JsonSettingsSchema { + return this.widgetConfigComponent.modelValue?.dataKeySettingsSchema; + } + + get isEntityDatasource(): boolean { + return [DatasourceType.device, DatasourceType.entity].includes(this.datasourceType); + } + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder, + private dialog: MatDialog, + private cd: ChangeDetectorRef, + public translate: TranslateService, + public truncate: TruncatePipe, + private dataKeysPanelComponent: DataKeysPanelComponent, + private widgetConfigComponent: WidgetConfigComponent) { + } + + ngOnInit() { + this.keyFormControl = this.fb.control(''); + this.keyRowFormGroup = this.fb.group({ + label: [null, []], + color: [null, []], + units: [null, []], + decimals: [null, []], + }); + this.keyRowFormGroup.valueChanges.subscribe( + () => this.updateModel() + ); + this.filteredKeys = this.keyFormControl.valueChanges + .pipe( + tap((value: string | DataKey) => { + if (value && typeof value !== 'string') { + this.addKeyFromChipValue(value); + } else if (value === null) { + this.clearKeyChip(this.keyInput.nativeElement.value); + } + }), + filter((value) => typeof value === 'string'), + map((value) => value ? (typeof value === 'string' ? value : value.name) : ''), + mergeMap(name => this.fetchKeys(name) ), + share() + ); + } + + private reset() { + if (this.keyInput) { + this.keyInput.nativeElement.value = ''; + } + this.keyFormControl.patchValue('', {emitEvent: false}); + this.latestKeySearchTextResult = null; + } + + ngOnChanges(changes: SimpleChanges): void { + for (const propName of Object.keys(changes)) { + const change = changes[propName]; + if (!change.firstChange && change.currentValue !== change.previousValue) { + if (['deviceId', 'entityAliasId'].includes(propName)) { + this.clearKeySearchCache(); + } else if (['datasourceType'].includes(propName)) { + if ([DatasourceType.device, DatasourceType.entity].includes(change.previousValue) && + [DatasourceType.device, DatasourceType.entity].includes(change.currentValue)) { + this.clearKeySearchCache(); + } else { + this.clearKeySearchCache(); + setTimeout(() => { + this.reset(); + }, 1); + } + } + } + } + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (isDisabled) { + this.keyRowFormGroup.disable({emitEvent: false}); + } else { + this.keyRowFormGroup.enable({emitEvent: false}); + } + } + + writeValue(value: DataKey): void { + this.modelValue = value || {} as DataKey; + this.keyRowFormGroup.patchValue( + { + label: value?.label, + color: value?.color, + units: value?.units, + decimals: value?.decimals + }, {emitEvent: false} + ); + this.cd.markForCheck(); + } + + dataKeyHasAggregation(): boolean { + return this.widgetConfigComponent.widgetType === widgetType.latest && this.modelValue?.type === DataKeyType.timeseries + && this.modelValue?.aggregationType && this.modelValue?.aggregationType !== AggregationType.NONE; + } + + dataKeyHasPostprocessing(): boolean { + return !!this.modelValue?.postFuncBody; + } + + displayKeyFn(key?: DataKey): string | undefined { + return key ? key.name : undefined; + } + + createKey(name: string, dataKeyType: DataKeyType = this.dataKeyType) { + this.addKeyFromChipValue({name: name ? name.trim() : '', type: dataKeyType}); + } + + addKey(event: MatChipInputEvent): void { + const value = event.value; + if ((value || '').trim() && this.dataKeyType) { + this.addKeyFromChipValue({name: value.trim(), type: this.dataKeyType}); + } else { + this.clearKeyChip(); + } + } + + editKey() { + + } + + removeKey() { + this.modelValue = {} as DataKey; + this.updateModel(); + this.clearKeyChip(); + } + + textIsNotEmpty(text: string): boolean { + return text && text.length > 0; + } + + clearKeyChip(value: string = '', focus = true) { + this.autocomplete.closePanel(); + this.keyInput.nativeElement.value = value; + this.keyFormControl.patchValue(value, {emitEvent: focus}); + if (focus) { + setTimeout(() => { + this.keyInput.nativeElement.blur(); + this.keyInput.nativeElement.focus(); + }, 0); + } + } + + onKeyInputFocus() { + if (!this.modelValue.type) { + this.keyFormControl.updateValueAndValidity({onlySelf: true, emitEvent: true}); + } + } + + private fetchKeys(searchText?: string): Observable> { + if (this.keySearchText !== searchText || this.latestKeySearchTextResult === null) { + this.keySearchText = searchText; + const dataKeyFilter = this.createDataKeyFilter(this.keySearchText); + return this.getKeys().pipe( + map(name => name.filter(dataKeyFilter)), + tap(res => this.latestKeySearchTextResult = res) + ); + } + return of(this.latestKeySearchTextResult); + } + + private getKeys(): Observable> { + if (this.keyFetchObservable$ === null) { + let fetchObservable: Observable>; + if (this.datasourceType === DatasourceType.function) { + const targetKeysList = this.widgetType === widgetType.alarm ? this.alarmKeys : this.functionTypeKeys; + fetchObservable = of(targetKeysList); + } else if (this.datasourceType === DatasourceType.entity && this.entityAliasId || + this.datasourceType === DatasourceType.device && this.deviceId) { + const dataKeyTypes = [DataKeyType.timeseries]; + if (this.widgetType === widgetType.latest || this.widgetType === widgetType.alarm) { + dataKeyTypes.push(DataKeyType.attribute); + dataKeyTypes.push(DataKeyType.entityField); + if (this.widgetType === widgetType.alarm) { + dataKeyTypes.push(DataKeyType.alarm); + } + } + if (this.datasourceType === DatasourceType.device) { + fetchObservable = this.callbacks.fetchEntityKeysForDevice(this.deviceId, dataKeyTypes); + } else { + fetchObservable = this.callbacks.fetchEntityKeys(this.entityAliasId, dataKeyTypes); + } + } else { + fetchObservable = of([]); + } + this.keyFetchObservable$ = fetchObservable.pipe( + publishReplay(1), + refCount() + ); + } + return this.keyFetchObservable$; + } + + private createDataKeyFilter(query: string): (key: DataKey) => boolean { + const lowercaseQuery = query.toLowerCase(); + return key => key.name.toLowerCase().startsWith(lowercaseQuery); + } + + private addKeyFromChipValue(chip: DataKey) { + this.modelValue = this.callbacks.generateDataKey(chip.name, chip.type, this.datakeySettingsSchema); + if (!this.keyRowFormGroup.get('label').value) { + this.keyRowFormGroup.get('label').patchValue(this.modelValue.label, {emitEvent: false}); + } + this.updateModel(); + this.clearKeyChip('', false); + } + + private clearKeySearchCache() { + this.keySearchText = ''; + this.keyFetchObservable$ = null; + this.latestKeySearchTextResult = null; + } + + private updateModel() { + const value: DataKey = this.keyRowFormGroup.value; + this.modelValue = {...this.modelValue, ...value}; + this.propagateChange(this.modelValue); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html new file mode 100644 index 0000000000..b4e8795f8f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html @@ -0,0 +1,66 @@ + +
+
{{ panelTitle }}
+
+
+
datakey.key
+
datakey.label
+
datakey.color
+
widget-config.units-short
+
widget-config.decimals-short
+
+
+
+ + +
+ + +
+
+
+
+
+ +
+
+ + {{ noKeysText }} + diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.scss new file mode 100644 index 0000000000..944181f085 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.scss @@ -0,0 +1,71 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-data-keys-table { + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 6px; + display: flex; + flex-direction: column; + gap: 12px; + padding-bottom: 12px; + .tb-data-keys-header { + height: 48px; + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + display: flex; + flex-direction: row; + place-content: center flex-start; + align-items: center; + gap: 12px; + padding-left: 12px; + padding-right: 12px; + .tb-data-keys-header-cell { + font-weight: 400; + font-size: 14px; + line-height: 20px; + letter-spacing: 0.2px; + color: rgba(0, 0, 0, 0.54); + } + } + .tb-data-keys-body { + display: flex; + flex-direction: column; + gap: 12px; + } + .tb-prompt { + height: 38px; + } +} + +.tb-data-keys-table-row { + height: 38px; + display: flex; + flex-direction: row; + gap: 12px; + background: #fff; + + .tb-data-keys-table-row-buttons { + display: flex; + flex-direction: row; + button.mat-mdc-icon-button.mat-mdc-button-base { + padding: 7px; + width: 38px; + height: 38px; + .mat-icon { + color: rgba(0, 0, 0, 0.38); + } + } + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts new file mode 100644 index 0000000000..c27de8549b --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts @@ -0,0 +1,234 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { + ChangeDetectorRef, + Component, + forwardRef, + Input, + OnChanges, + OnInit, + SimpleChanges, + ViewEncapsulation +} from '@angular/core'; +import { + AbstractControl, + ControlValueAccessor, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + UntypedFormArray, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + Validator +} from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKey, DatasourceType, JsonSettingsSchema, widgetType } from '@shared/models/widget.models'; +import { dataKeyRowValidator } from '@home/components/widget/config/basic/common/data-key-row.component'; +import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { alarmFields } from '@shared/models/alarm.models'; +import { UtilsService } from '@core/services/utils.service'; +import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; + +@Component({ + selector: 'tb-data-keys-panel', + templateUrl: './data-keys-panel.component.html', + styleUrls: ['./data-keys-panel.component.scss', '../../widget-config.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => DataKeysPanelComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => DataKeysPanelComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class DataKeysPanelComponent implements ControlValueAccessor, OnInit, OnChanges, Validator { + + @Input() + disabled: boolean; + + @Input() + panelTitle: string; + + @Input() + addKeyTitle: string; + + @Input() + removeKeyTitle: string; + + @Input() + noKeysText: string; + + @Input() + datasourceType: DatasourceType; + + @Input() + entityAliasId: string; + + @Input() + deviceId: string; + + dataKeyType: DataKeyType; + alarmKeys: Array; + functionTypeKeys: Array; + + keysListFormGroup: UntypedFormGroup; + + get widgetType(): widgetType { + return this.widgetConfigComponent.widgetType; + } + + get callbacks(): DataKeysCallbacks { + return this.widgetConfigComponent.widgetConfigCallbacks; + } + + get datakeySettingsSchema(): JsonSettingsSchema { + return this.widgetConfigComponent.modelValue?.dataKeySettingsSchema; + } + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder, + private dialog: MatDialog, + private cd: ChangeDetectorRef, + private utils: UtilsService, + private widgetConfigComponent: WidgetConfigComponent) { + } + + ngOnInit() { + this.keysListFormGroup = this.fb.group({ + keys: [this.fb.array([]), []] + }); + this.keysListFormGroup.valueChanges.subscribe( + (val) => this.propagateChange(this.keysListFormGroup.get('keys').value) + ); + this.alarmKeys = []; + for (const name of Object.keys(alarmFields)) { + this.alarmKeys.push({ + name, + type: DataKeyType.alarm + }); + } + this.functionTypeKeys = []; + for (const type of this.utils.getPredefinedFunctionsList()) { + this.functionTypeKeys.push({ + name: type, + type: DataKeyType.function + }); + } + this.updateParams(); + } + + ngOnChanges(changes: SimpleChanges): void { + for (const propName of Object.keys(changes)) { + const change = changes[propName]; + if (!change.firstChange && change.currentValue !== change.previousValue) { + if (['datasourceType'].includes(propName)) { + this.updateParams(); + } + } + } + } + + private updateParams() { + if (this.datasourceType === DatasourceType.function) { + this.dataKeyType = DataKeyType.function; + } else { + if (this.widgetType !== widgetType.latest && this.widgetType !== widgetType.alarm) { + this.dataKeyType = DataKeyType.timeseries; + } else { + this.dataKeyType = null; + } + } + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (isDisabled) { + this.keysListFormGroup.disable({emitEvent: false}); + } else { + this.keysListFormGroup.enable({emitEvent: false}); + } + } + + writeValue(value: DataKey[] | undefined): void { + this.keysListFormGroup.setControl('keys', this.prepareKeysFormArray(value), {emitEvent: false}); + } + + public validate(c: UntypedFormControl) { + return this.keysListFormGroup.valid ? null : { + dataKeyRows: { + valid: false, + }, + }; + } + + keyDrop(event: CdkDragDrop) { + const keysArray = this.keysListFormGroup.get('keys') as UntypedFormArray; + const key = keysArray.at(event.previousIndex); + keysArray.removeAt(event.previousIndex); + keysArray.insert(event.currentIndex, key); + } + + keysFormArray(): UntypedFormArray { + return this.keysListFormGroup.get('keys') as UntypedFormArray; + } + + trackByKey(index: number, keyControl: AbstractControl): any { + return keyControl; + } + + removeKey(index: number) { + (this.keysListFormGroup.get('keys') as UntypedFormArray).removeAt(index); + } + + addKey() { + const dataKey = this.callbacks.generateDataKey('', null, this.datakeySettingsSchema); + const keysArray = this.keysListFormGroup.get('keys') as UntypedFormArray; + const keyControl = this.fb.control(dataKey, [dataKeyRowValidator]); + keysArray.push(keyControl); + this.keysListFormGroup.updateValueAndValidity(); + if (!this.keysListFormGroup.valid) { + this.propagateChange(this.keysListFormGroup.get('keys').value); + } + } + + private prepareKeysFormArray(keys: DataKey[] | undefined): UntypedFormArray { + const keysControls: Array = []; + if (keys) { + keys.forEach((key) => { + keysControls.push(this.fb.control(key, [dataKeyRowValidator])); + }); + } + return this.fb.array(keysControls); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.scss index 3013bf78ae..7d01f41cb5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.scss @@ -22,92 +22,92 @@ input.tb-dragging { display: none; } +} - .mat-mdc-chip.mat-mdc-standard-chip.tb-datakey-chip { - overflow: hidden; - line-height: 20px; - height: 32px; +.mat-mdc-chip.mat-mdc-standard-chip.tb-datakey-chip { + overflow: hidden; + line-height: 20px; + height: 32px; - &.mdc-evolution-chip--with-trailing-action { - .mdc-evolution-chip__action--primary { - padding-left: 4px; - padding-right: 12px; - } + &.mdc-evolution-chip--with-trailing-action { + .mdc-evolution-chip__action--primary { + padding-left: 4px; + padding-right: 12px; } + } - .mat-mdc-chip-action { + .mat-mdc-chip-action { + overflow: hidden; + .mat-mdc-chip-action-label { overflow: hidden; - .mat-mdc-chip-action-label { - overflow: hidden; - } } - .tb-attribute-chip { - max-width: 100%; - color: rgb(66, 66, 66); - .tb-chip-drag-handle { - padding: 3px; - height: 24px; - cursor: move; - mat-icon { - pointer-events: none; - } + } + .tb-attribute-chip { + max-width: 100%; + color: rgb(66, 66, 66); + .tb-chip-drag-handle { + padding: 3px; + height: 24px; + cursor: move; + mat-icon { + pointer-events: none; } - .tb-chip-labels { - display: flex; - flex-direction: row; - align-items: center; - min-width: 0; - background: rgba(0, 0, 0, 0.04); - border-radius: 100px; - padding: 2px 10px; - .tb-chip-label { - font-weight: normal; - font-size: 14px; - line-height: 20px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - .mat-icon.tb-datakey-icon { - margin-right: 4px; - margin-left: 4px; - } - .tb-agg-func { - font-style: italic; - color: #0c959c; - } + } + .tb-chip-labels { + display: flex; + flex-direction: row; + align-items: center; + min-width: 0; + background: rgba(0, 0, 0, 0.04); + border-radius: 100px; + padding: 2px 10px; + .tb-chip-label { + font-weight: normal; + font-size: 14px; + line-height: 20px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + .mat-icon.tb-datakey-icon { + margin-right: 4px; + margin-left: 4px; } - .tb-chip-separator { - white-space: pre; + .tb-agg-func { + font-style: italic; + color: #0c959c; } } - .mat-mdc-chip-remove.mat-mdc-icon-button { - color: inherit; - opacity: inherit; + .tb-chip-separator { + white-space: pre; } } - - &.tb-datakey-chip-dnd-placeholder { - min-width: 120px; - border: 2px dashed rgba(0, 0, 0, 0.2); - } - &.tb-chip-dragging { - display: none; + .mat-mdc-chip-remove.mat-mdc-icon-button { + color: inherit; + opacity: inherit; } + } + + &.tb-datakey-chip-dnd-placeholder { + min-width: 120px; + border: 2px dashed rgba(0, 0, 0, 0.2); + } + &.tb-chip-dragging { + display: none; + } + .tb-dragging-chip-image-fill { + background-color: rgba(0,0,0,0.3); + border-radius: var(--mdc-chip-container-shape-radius, 16px 16px 16px 16px); + display: none; + pointer-events: none; + } + .tb-dragging-chip-image { + background-color: var(--mdc-chip-elevated-container-color, transparent); + border-radius: var(--mdc-chip-container-shape-radius, 16px 16px 16px 16px); + overflow: hidden; + height: 32px; + line-height: 20px; .tb-dragging-chip-image-fill { - background-color: rgba(0,0,0,0.3); - border-radius: var(--mdc-chip-container-shape-radius, 16px 16px 16px 16px); - display: none; - pointer-events: none; - } - .tb-dragging-chip-image { - background-color: var(--mdc-chip-elevated-container-color, transparent); - border-radius: var(--mdc-chip-container-shape-radius, 16px 16px 16px 16px); - overflow: hidden; - height: 32px; - line-height: 20px; - .tb-dragging-chip-image-fill { - display: block; - } + display: block; } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html index 5cf519637b..ab7411488e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html @@ -61,7 +61,7 @@
-
+
Date: Tue, 6 Jun 2023 11:52:08 +0300 Subject: [PATCH 130/207] added etag header for resources/{id}/download endpoint --- .../controller/TbResourceController.java | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index ea151bd0c5..d9c846e4bd 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -15,12 +15,15 @@ */ package org.thingsboard.server.controller; +import com.google.common.hash.HashCode; +import com.google.common.hash.Hashing; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ByteArrayResource; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -47,6 +50,7 @@ import org.thingsboard.server.service.resource.TbResourceService; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; +import javax.servlet.http.HttpServletRequest; import java.util.Base64; import java.util.List; @@ -85,17 +89,42 @@ public class TbResourceController extends BaseController { @RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET) @ResponseBody public ResponseEntity downloadResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException { + @PathVariable(RESOURCE_ID) String strResourceId, HttpServletRequest request) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); TbResource tbResource = checkResourceId(resourceId, Operation.READ); ByteArrayResource resource = new ByteArrayResource(Base64.getDecoder().decode(tbResource.getData().getBytes())); + + HashCode hashCode = Hashing.sha256().hashBytes(resource.getByteArray()); + String ifNoneMatch = request.getHeader("If-None-Match"); + if (ifNoneMatch != null) { + if (ifNoneMatch.equals(hashCode.toString())) { + return ResponseEntity.status(HttpStatus.NOT_MODIFIED) + .eTag(hashCode.toString()).build(); + } + } + + String mediaType; + switch (tbResource.getResourceType()) { + case LWM2M_MODEL: + mediaType = "application/xml"; + break; + case JKS: + mediaType = "application/x-java-keystore"; + break; + case PKCS_12: + mediaType = "application/x-pkcs12"; + break; + default: mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE; + } + return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + tbResource.getFileName()) .header("x-filename", tbResource.getFileName()) .contentLength(resource.contentLength()) - .contentType(MediaType.APPLICATION_OCTET_STREAM) + .header("Content-Type", mediaType) + .eTag(hashCode.toString()) .body(resource); } From 3955c2f0186f8b252e86ef5313512de863aaec15 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 6 Jun 2023 13:24:12 +0300 Subject: [PATCH 131/207] fixed rpc queue stuck issue & improvements to rpc logging --- .../device/DeviceActorMessageProcessor.java | 103 ++++++++++++------ application/src/main/resources/logback.xml | 3 + 2 files changed, 70 insertions(+), 36 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 934f309480..21c77a7fc7 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -182,13 +182,15 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso void processRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg) { ToDeviceRpcRequest request = msg.getMsg(); + UUID rpcId = request.getId(); + log.debug("[{}][{}] Received rpc request to process ...", deviceId, rpcId); ToDeviceRpcRequestMsg rpcRequest = creteToDeviceRpcRequestMsg(request); long timeout = request.getExpirationTime() - System.currentTimeMillis(); boolean persisted = request.isPersisted(); if (timeout <= 0) { - log.debug("[{}][{}] Ignoring message due to exp time reached, {}", deviceId, request.getId(), request.getExpirationTime()); + log.debug("[{}][{}] Ignoring message due to exp time reached, {}", deviceId, rpcId, request.getExpirationTime()); if (persisted) { createRpc(request, RpcStatus.EXPIRED); } @@ -198,8 +200,9 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } boolean sent = false; + int requestId = rpcRequest.getRequestId(); if (systemContext.isEdgesEnabled() && edgeId != null) { - log.debug("[{}][{}] device is related to edge [{}]. Saving RPC request to edge queue", tenantId, deviceId, edgeId.getId()); + log.debug("[{}][{}] device is related to edge: [{}]. Saving rpc request: [{}][{}] to edge queue", tenantId, deviceId, edgeId.getId(), rpcId, requestId); try { saveRpcRequestToEdgeQueue(request, rpcRequest.getRequestId()).get(); sent = true; @@ -209,10 +212,11 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } else if (isSendNewRpcAvailable()) { sent = rpcSubscriptions.size() > 0; Set syncSessionSet = new HashSet<>(); - rpcSubscriptions.forEach((key, value) -> { - sendToTransport(rpcRequest, key, value.getNodeId()); - if (SessionType.SYNC == value.getType()) { - syncSessionSet.add(key); + rpcSubscriptions.forEach((sessionId, sessionInfo) -> { + log.debug("[{}][{}][{}][{}] send rpc request to transport ...", deviceId, sessionId, rpcId, requestId); + sendToTransport(rpcRequest, sessionId, sessionInfo.getNodeId()); + if (SessionType.SYNC == sessionInfo.getType()) { + syncSessionSet.add(sessionId); } }); log.trace("Rpc syncSessionSet [{}] subscription after sent [{}]", syncSessionSet, rpcSubscriptions); @@ -221,28 +225,32 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso if (persisted) { ObjectNode response = JacksonUtil.newObjectNode(); - response.put("rpcId", request.getId().toString()); + response.put("rpcId", rpcId.toString()); systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(msg.getMsg().getId(), JacksonUtil.toString(response), null)); } if (!persisted && request.isOneway() && sent) { - log.debug("[{}] Rpc command response sent [{}]!", deviceId, request.getId()); + log.debug("[{}] Rpc command response sent [{}][{}]!", deviceId, rpcId, requestId); systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(msg.getMsg().getId(), null, null)); } else { registerPendingRpcRequest(context, msg, sent, rpcRequest, timeout); } if (sent) { - log.debug("[{}] RPC request {} is sent!", deviceId, request.getId()); + log.debug("[{}][{}][{}] Rpc request is sent!", deviceId, rpcId, requestId); } else { - log.debug("[{}] RPC request {} is NOT sent!", deviceId, request.getId()); + log.debug("[{}][{}][{}] Rpc request is NOT sent!", deviceId, rpcId, requestId); } } + private UUID getRpcIdFromRequest(ToDeviceRpcRequestMsg request) { + return new UUID(request.getRequestIdMSB(), request.getRequestIdLSB()); + } + private boolean isSendNewRpcAvailable() { return !rpcSequential || toDeviceRpcPendingMap.values().stream().filter(md -> !md.isDelivered()).findAny().isEmpty(); } - private Rpc createRpc(ToDeviceRpcRequest request, RpcStatus status) { + private void createRpc(ToDeviceRpcRequest request, RpcStatus status) { Rpc rpc = new Rpc(new RpcId(request.getId())); rpc.setCreatedTime(System.currentTimeMillis()); rpc.setTenantId(tenantId); @@ -251,7 +259,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso rpc.setRequest(JacksonUtil.valueToTree(request)); rpc.setStatus(status); rpc.setAdditionalInfo(JacksonUtil.toJsonNode(request.getAdditionalInfo())); - return systemContext.getTbRpcService().save(tenantId, rpc); + systemContext.getTbRpcService().save(tenantId, rpc); } private ToDeviceRpcRequestMsg creteToDeviceRpcRequestMsg(ToDeviceRpcRequest request) { @@ -280,7 +288,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } void processRemoveRpc(TbActorCtx context, RemoveRpcActorMsg msg) { - log.debug("[{}] Processing remove rpc command", msg.getRequestId()); + UUID requestId = msg.getRequestId(); + log.debug("[{}][{}] Received remove rpc request ...", deviceId, requestId); Map.Entry entry = null; for (Map.Entry e : toDeviceRpcPendingMap.entrySet()) { if (e.getValue().getMsg().getMsg().getId().equals(msg.getRequestId())) { @@ -290,36 +299,42 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } if (entry != null) { + Integer key = entry.getKey(); if (entry.getValue().isDelivered()) { - toDeviceRpcPendingMap.remove(entry.getKey()); + toDeviceRpcPendingMap.remove(key); } else { Optional> firstRpc = getFirstRpc(); - if (firstRpc.isPresent() && entry.getKey().equals(firstRpc.get().getKey())) { - toDeviceRpcPendingMap.remove(entry.getKey()); + if (firstRpc.isPresent() && key.equals(firstRpc.get().getKey())) { + toDeviceRpcPendingMap.remove(key); + log.debug("[{}][{}][{}] Removed pending rpc! Going to send next pending request ...", deviceId, requestId, key); sendNextPendingRequest(context); } else { - toDeviceRpcPendingMap.remove(entry.getKey()); + toDeviceRpcPendingMap.remove(key); } } } } private void registerPendingRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { + log.debug("[{}][{}][{}] Registering pending rpc request...", deviceId, getRpcIdFromRequest(rpcRequest), rpcRequest.getRequestId()); toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); scheduleMsgWithDelay(context, timeoutMsg, timeoutMsg.getTimeout()); } void processServerSideRpcTimeout(TbActorCtx context, DeviceActorServerSideRpcTimeoutMsg msg) { - ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId()); + Integer requestId = msg.getId(); + ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(requestId); if (requestMd != null) { - log.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId()); + UUID rpcId = requestMd.getMsg().getMsg().getId(); + log.debug("[{}][{}][{}] Rpc request timeout detected!", deviceId, rpcId, requestId); if (requestMd.getMsg().getMsg().isPersisted()) { - systemContext.getTbRpcService().save(tenantId, new RpcId(requestMd.getMsg().getMsg().getId()), RpcStatus.EXPIRED, null); + systemContext.getTbRpcService().save(tenantId, new RpcId(rpcId), RpcStatus.EXPIRED, null); } - systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(), + systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(rpcId, null, requestMd.isSent() ? RpcError.TIMEOUT : RpcError.NO_ACTIVE_CONNECTION)); if (!requestMd.isDelivered()) { + log.debug("[{}][{}][{}] Pending rpc timeout detected! Going to send next pending request ...", deviceId, rpcId, requestId); sendNextPendingRequest(context); } } @@ -328,13 +343,13 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso private void sendPendingRequests(TbActorCtx context, UUID sessionId, String nodeId) { SessionType sessionType = getSessionType(sessionId); if (!toDeviceRpcPendingMap.isEmpty()) { - log.debug("[{}] Pushing {} pending RPC messages to new async session [{}]", deviceId, toDeviceRpcPendingMap.size(), sessionId); + log.debug("[{}][{}] Pushing {} pending rpc messages to new async session!", deviceId, sessionId, toDeviceRpcPendingMap.size()); if (sessionType == SessionType.SYNC) { log.debug("[{}] Cleanup sync rpc session [{}]", deviceId, sessionId); rpcSubscriptions.remove(sessionId); } } else { - log.debug("[{}] No pending RPC messages for new async session [{}]", deviceId, sessionId); + log.debug("[{}] No pending rpc messages for new async session [{}]", deviceId, sessionId); } Set sentOneWayIds = new HashSet<>(); @@ -363,12 +378,13 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso return entry -> { ToDeviceRpcRequest request = entry.getValue().getMsg().getMsg(); ToDeviceRpcRequestBody body = request.getBody(); + Integer requestId = entry.getKey(); if (request.isOneway() && !rpcSequential) { - sentOneWayIds.add(entry.getKey()); + sentOneWayIds.add(requestId); systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(request.getId(), null, null)); } ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder() - .setRequestId(entry.getKey()) + .setRequestId(requestId) .setMethodName(body.getMethod()) .setParams(body.getParams()) .setExpirationTime(request.getExpirationTime()) @@ -377,6 +393,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso .setOneway(request.isOneway()) .setPersisted(request.isPersisted()) .build(); + log.debug("[{}][{}][{}][{}] Send pending rpc request to transport ...", deviceId, sessionId, getRpcIdFromRequest(rpcRequest), requestId); sendToTransport(rpcRequest, sessionId, nodeId); }; } @@ -569,18 +586,26 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso private void processRpcResponses(TbActorCtx context, SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg responseMsg) { UUID sessionId = getSessionId(sessionInfo); - log.debug("[{}] Processing rpc command response [{}]", deviceId, sessionId); + log.debug("[{}][{}] Processing rpc command response: {}", deviceId, sessionId, responseMsg); ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); boolean success = requestMd != null; if (success) { + boolean delivered = requestMd.isDelivered(); boolean hasError = StringUtils.isNotEmpty(responseMsg.getError()); try { - String payload = hasError ? responseMsg.getError() : responseMsg.getPayload(); + String payload; + if (hasError) { + payload = responseMsg.getError(); + } else if (delivered) { + payload = responseMsg.getPayload(); + } else { + payload = "Received response for undelivered rpc: " + responseMsg.getPayload(); + } systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor( new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(), payload, null)); if (requestMd.getMsg().getMsg().isPersisted()) { - RpcStatus status = hasError ? RpcStatus.FAILED : RpcStatus.SUCCESSFUL; + RpcStatus status = hasError || !delivered ? RpcStatus.FAILED : RpcStatus.SUCCESSFUL; JsonNode response; try { response = JacksonUtil.toJsonNode(payload); @@ -590,25 +615,30 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso systemContext.getTbRpcService().save(tenantId, new RpcId(requestMd.getMsg().getMsg().getId()), status, response); } } finally { - if (hasError && !requestMd.isDelivered()) { + if (!delivered) { + String errorResponse = hasError ? "error" : ""; + log.debug("[{}][{}][{}] Received {} response for undelivered rpc! Going to send next pending request ...", deviceId, sessionId, responseMsg.getRequestId(), errorResponse); sendNextPendingRequest(context); } } } else { - log.debug("[{}] Rpc command response [{}] is stale!", deviceId, responseMsg.getRequestId()); + log.debug("[{}][{}][{}] Rpc command response is stale!", deviceId, sessionId, responseMsg.getRequestId()); } } private void processRpcResponseStatus(TbActorCtx context, SessionInfoProto sessionInfo, ToDeviceRpcResponseStatusMsg responseMsg) { UUID rpcId = new UUID(responseMsg.getRequestIdMSB(), responseMsg.getRequestIdLSB()); RpcStatus status = RpcStatus.valueOf(responseMsg.getStatus()); - ToDeviceRpcRequestMetadata md = toDeviceRpcPendingMap.get(responseMsg.getRequestId()); + UUID sessionId = getSessionId(sessionInfo); + int requestId = responseMsg.getRequestId(); + log.debug("[{}][{}][{}][{}] Processing rpc command response status: [{}]", deviceId, sessionId, rpcId, requestId, status); + ToDeviceRpcRequestMetadata md = toDeviceRpcPendingMap.get(requestId); if (md != null) { JsonNode response = null; if (status.equals(RpcStatus.DELIVERED)) { if (md.getMsg().getMsg().isOneway()) { - toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); + toDeviceRpcPendingMap.remove(requestId); if (rpcSequential) { systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(rpcId, null, null)); } @@ -619,7 +649,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso Integer maxRpcRetries = md.getMsg().getMsg().getRetries(); maxRpcRetries = maxRpcRetries == null ? systemContext.getMaxRpcRetries() : Math.min(maxRpcRetries, systemContext.getMaxRpcRetries()); if (maxRpcRetries <= md.getRetries()) { - toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); + toDeviceRpcPendingMap.remove(requestId); status = RpcStatus.FAILED; response = JacksonUtil.newObjectNode().put("error", "There was a Timeout and all retry attempts have been exhausted. Retry attempts set: " + maxRpcRetries); } else { @@ -631,10 +661,11 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso systemContext.getTbRpcService().save(tenantId, new RpcId(rpcId), status, response); } if (status != RpcStatus.SENT) { + log.debug("[{}][{}][{}][{}] Rpc was {}! Going to send next pending request ...", deviceId, sessionId, rpcId, requestId, status.name().toLowerCase()); sendNextPendingRequest(context); } } else { - log.info("[{}][{}] Rpc has already removed from pending map.", deviceId, rpcId); + log.warn("[{}][{}][{}][{}] Rpc has already been removed from pending map.", deviceId, sessionId, rpcId, requestId); } } @@ -662,7 +693,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso private void processSubscriptionCommands(TbActorCtx context, SessionInfoProto sessionInfo, SubscribeToRPCMsg subscribeCmd) { UUID sessionId = getSessionId(sessionInfo); if (subscribeCmd.getUnsubscribe()) { - log.debug("[{}] Canceling rpc subscription for session [{}]", deviceId, sessionId); + log.debug("[{}] Canceling rpc subscription for session: [{}]", deviceId, sessionId); rpcSubscriptions.remove(sessionId); } else { SessionInfoMetaData sessionMD = sessions.get(sessionId); @@ -670,7 +701,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso sessionMD = new SessionInfoMetaData(new SessionInfo(subscribeCmd.getSessionType(), sessionInfo.getNodeId())); } sessionMD.setSubscribedToRPC(true); - log.debug("[{}] Registering rpc subscription for session [{}]", deviceId, sessionId); + log.debug("[{}] Registered rpc subscription for session: [{}] Going to check for pending requests ...", deviceId, sessionId); rpcSubscriptions.put(sessionId, sessionMD.getSessionInfo()); sendPendingRequests(context, sessionId, sessionInfo.getNodeId()); dumpSessions(); diff --git a/application/src/main/resources/logback.xml b/application/src/main/resources/logback.xml index 7159a0256d..eaf6ace29e 100644 --- a/application/src/main/resources/logback.xml +++ b/application/src/main/resources/logback.xml @@ -51,6 +51,9 @@ + + + From 509e630439ab45cf3fb1eb4e34021ad9cd1d0af6 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 6 Jun 2023 13:29:17 +0300 Subject: [PATCH 132/207] fix log typo --- .../server/actors/device/DeviceActorMessageProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 21c77a7fc7..794528a2b8 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -701,8 +701,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso sessionMD = new SessionInfoMetaData(new SessionInfo(subscribeCmd.getSessionType(), sessionInfo.getNodeId())); } sessionMD.setSubscribedToRPC(true); - log.debug("[{}] Registered rpc subscription for session: [{}] Going to check for pending requests ...", deviceId, sessionId); rpcSubscriptions.put(sessionId, sessionMD.getSessionInfo()); + log.debug("[{}] Registered rpc subscription for session: [{}] Going to check for pending requests ...", deviceId, sessionId); sendPendingRequests(context, sessionId, sessionInfo.getNodeId()); dumpSessions(); } From d500d5cb175670eb12e5a35ee9000dd04dca658d Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 6 Jun 2023 14:30:02 +0300 Subject: [PATCH 133/207] updated RPC based logs to use RPC keyword instead of rpc --- .../device/DeviceActorMessageProcessor.java | 65 ++++++++++--------- .../transport/mqtt/MqttTransportHandler.java | 29 +++++---- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 794528a2b8..71d3d43e00 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -183,7 +183,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso void processRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg) { ToDeviceRpcRequest request = msg.getMsg(); UUID rpcId = request.getId(); - log.debug("[{}][{}] Received rpc request to process ...", deviceId, rpcId); + log.debug("[{}][{}] Received RPC request to process ...", deviceId, rpcId); ToDeviceRpcRequestMsg rpcRequest = creteToDeviceRpcRequestMsg(request); long timeout = request.getExpirationTime() - System.currentTimeMillis(); @@ -202,18 +202,18 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso boolean sent = false; int requestId = rpcRequest.getRequestId(); if (systemContext.isEdgesEnabled() && edgeId != null) { - log.debug("[{}][{}] device is related to edge: [{}]. Saving rpc request: [{}][{}] to edge queue", tenantId, deviceId, edgeId.getId(), rpcId, requestId); + log.debug("[{}][{}] device is related to edge: [{}]. Saving RPC request: [{}][{}] to edge queue", tenantId, deviceId, edgeId.getId(), rpcId, requestId); try { saveRpcRequestToEdgeQueue(request, rpcRequest.getRequestId()).get(); sent = true; } catch (InterruptedException | ExecutionException e) { - log.error("[{}][{}][{}] Failed to save rpc request to edge queue {}", tenantId, deviceId, edgeId.getId(), request, e); + log.error("[{}][{}][{}] Failed to save RPC request to edge queue {}", tenantId, deviceId, edgeId.getId(), request, e); } } else if (isSendNewRpcAvailable()) { sent = rpcSubscriptions.size() > 0; Set syncSessionSet = new HashSet<>(); rpcSubscriptions.forEach((sessionId, sessionInfo) -> { - log.debug("[{}][{}][{}][{}] send rpc request to transport ...", deviceId, sessionId, rpcId, requestId); + log.debug("[{}][{}][{}][{}] send RPC request to transport ...", deviceId, sessionId, rpcId, requestId); sendToTransport(rpcRequest, sessionId, sessionInfo.getNodeId()); if (SessionType.SYNC == sessionInfo.getType()) { syncSessionSet.add(sessionId); @@ -230,15 +230,15 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } if (!persisted && request.isOneway() && sent) { - log.debug("[{}] Rpc command response sent [{}][{}]!", deviceId, rpcId, requestId); + log.debug("[{}] RPC command response sent [{}][{}]!", deviceId, rpcId, requestId); systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(msg.getMsg().getId(), null, null)); } else { registerPendingRpcRequest(context, msg, sent, rpcRequest, timeout); } if (sent) { - log.debug("[{}][{}][{}] Rpc request is sent!", deviceId, rpcId, requestId); + log.debug("[{}][{}][{}] RPC request is sent!", deviceId, rpcId, requestId); } else { - log.debug("[{}][{}][{}] Rpc request is NOT sent!", deviceId, rpcId, requestId); + log.debug("[{}][{}][{}] RPC request is NOT sent!", deviceId, rpcId, requestId); } } @@ -277,19 +277,19 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } void processRpcResponsesFromEdge(TbActorCtx context, FromDeviceRpcResponseActorMsg responseMsg) { - log.debug("[{}] Processing rpc command response from edge session", deviceId); + log.debug("[{}] Processing RPC command response from edge session", deviceId); ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); boolean success = requestMd != null; if (success) { systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(responseMsg.getMsg()); } else { - log.debug("[{}] Rpc command response [{}] is stale!", deviceId, responseMsg.getRequestId()); + log.debug("[{}] RPC command response [{}] is stale!", deviceId, responseMsg.getRequestId()); } } void processRemoveRpc(TbActorCtx context, RemoveRpcActorMsg msg) { UUID requestId = msg.getRequestId(); - log.debug("[{}][{}] Received remove rpc request ...", deviceId, requestId); + log.debug("[{}][{}] Received remove RPC request ...", deviceId, requestId); Map.Entry entry = null; for (Map.Entry e : toDeviceRpcPendingMap.entrySet()) { if (e.getValue().getMsg().getMsg().getId().equals(msg.getRequestId())) { @@ -306,7 +306,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso Optional> firstRpc = getFirstRpc(); if (firstRpc.isPresent() && key.equals(firstRpc.get().getKey())) { toDeviceRpcPendingMap.remove(key); - log.debug("[{}][{}][{}] Removed pending rpc! Going to send next pending request ...", deviceId, requestId, key); + log.debug("[{}][{}][{}] Removed pending RPC! Going to send next pending request ...", deviceId, requestId, key); sendNextPendingRequest(context); } else { toDeviceRpcPendingMap.remove(key); @@ -316,7 +316,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } private void registerPendingRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { - log.debug("[{}][{}][{}] Registering pending rpc request...", deviceId, getRpcIdFromRequest(rpcRequest), rpcRequest.getRequestId()); + log.debug("[{}][{}][{}] Registering pending RPC request...", deviceId, getRpcIdFromRequest(rpcRequest), rpcRequest.getRequestId()); toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); scheduleMsgWithDelay(context, timeoutMsg, timeoutMsg.getTimeout()); @@ -327,14 +327,14 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(requestId); if (requestMd != null) { UUID rpcId = requestMd.getMsg().getMsg().getId(); - log.debug("[{}][{}][{}] Rpc request timeout detected!", deviceId, rpcId, requestId); + log.debug("[{}][{}][{}] RPC request timeout detected!", deviceId, rpcId, requestId); if (requestMd.getMsg().getMsg().isPersisted()) { systemContext.getTbRpcService().save(tenantId, new RpcId(rpcId), RpcStatus.EXPIRED, null); } systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(rpcId, null, requestMd.isSent() ? RpcError.TIMEOUT : RpcError.NO_ACTIVE_CONNECTION)); if (!requestMd.isDelivered()) { - log.debug("[{}][{}][{}] Pending rpc timeout detected! Going to send next pending request ...", deviceId, rpcId, requestId); + log.debug("[{}][{}][{}] Pending RPC timeout detected! Going to send next pending request ...", deviceId, rpcId, requestId); sendNextPendingRequest(context); } } @@ -343,13 +343,13 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso private void sendPendingRequests(TbActorCtx context, UUID sessionId, String nodeId) { SessionType sessionType = getSessionType(sessionId); if (!toDeviceRpcPendingMap.isEmpty()) { - log.debug("[{}][{}] Pushing {} pending rpc messages to new async session!", deviceId, sessionId, toDeviceRpcPendingMap.size()); + log.debug("[{}][{}] Pushing {} pending RPC messages to new async session!", deviceId, sessionId, toDeviceRpcPendingMap.size()); if (sessionType == SessionType.SYNC) { - log.debug("[{}] Cleanup sync rpc session [{}]", deviceId, sessionId); + log.debug("[{}] Cleanup sync RPC session [{}]", deviceId, sessionId); rpcSubscriptions.remove(sessionId); } } else { - log.debug("[{}] No pending rpc messages for new async session [{}]", deviceId, sessionId); + log.debug("[{}] No pending RPC messages for new async session [{}]", deviceId, sessionId); } Set sentOneWayIds = new HashSet<>(); @@ -393,7 +393,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso .setOneway(request.isOneway()) .setPersisted(request.isPersisted()) .build(); - log.debug("[{}][{}][{}][{}] Send pending rpc request to transport ...", deviceId, sessionId, getRpcIdFromRequest(rpcRequest), requestId); + log.debug("[{}][{}][{}][{}] Send pending RPC request to transport ...", deviceId, sessionId, getRpcIdFromRequest(rpcRequest), requestId); sendToTransport(rpcRequest, sessionId, nodeId); }; } @@ -586,10 +586,11 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso private void processRpcResponses(TbActorCtx context, SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg responseMsg) { UUID sessionId = getSessionId(sessionInfo); - log.debug("[{}][{}] Processing rpc command response: {}", deviceId, sessionId, responseMsg); + log.debug("[{}][{}] Processing RPC command response: {}", deviceId, sessionId, responseMsg); ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); boolean success = requestMd != null; if (success) { + ToDeviceRpcRequest toDeviceRequestMsg = requestMd.getMsg().getMsg(); boolean delivered = requestMd.isDelivered(); boolean hasError = StringUtils.isNotEmpty(responseMsg.getError()); try { @@ -599,12 +600,12 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } else if (delivered) { payload = responseMsg.getPayload(); } else { - payload = "Received response for undelivered rpc: " + responseMsg.getPayload(); + payload = "Received response for undelivered RPC: " + responseMsg.getPayload(); } systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor( - new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(), + new FromDeviceRpcResponse(toDeviceRequestMsg.getId(), payload, null)); - if (requestMd.getMsg().getMsg().isPersisted()) { + if (toDeviceRequestMsg.isPersisted()) { RpcStatus status = hasError || !delivered ? RpcStatus.FAILED : RpcStatus.SUCCESSFUL; JsonNode response; try { @@ -612,17 +613,17 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } catch (IllegalArgumentException e) { response = JacksonUtil.newObjectNode().put("error", payload); } - systemContext.getTbRpcService().save(tenantId, new RpcId(requestMd.getMsg().getMsg().getId()), status, response); + systemContext.getTbRpcService().save(tenantId, new RpcId(toDeviceRequestMsg.getId()), status, response); } } finally { if (!delivered) { String errorResponse = hasError ? "error" : ""; - log.debug("[{}][{}][{}] Received {} response for undelivered rpc! Going to send next pending request ...", deviceId, sessionId, responseMsg.getRequestId(), errorResponse); + log.debug("[{}][{}][{}] Received {} response for undelivered RPC! Going to send next pending request ...", deviceId, sessionId, responseMsg.getRequestId(), errorResponse); sendNextPendingRequest(context); } } } else { - log.debug("[{}][{}][{}] Rpc command response is stale!", deviceId, sessionId, responseMsg.getRequestId()); + log.debug("[{}][{}][{}] RPC command response is stale!", deviceId, sessionId, responseMsg.getRequestId()); } } @@ -631,7 +632,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso RpcStatus status = RpcStatus.valueOf(responseMsg.getStatus()); UUID sessionId = getSessionId(sessionInfo); int requestId = responseMsg.getRequestId(); - log.debug("[{}][{}][{}][{}] Processing rpc command response status: [{}]", deviceId, sessionId, rpcId, requestId, status); + log.debug("[{}][{}][{}][{}] Processing RPC command response status: [{}]", deviceId, sessionId, rpcId, requestId, status); ToDeviceRpcRequestMetadata md = toDeviceRpcPendingMap.get(requestId); if (md != null) { @@ -661,11 +662,11 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso systemContext.getTbRpcService().save(tenantId, new RpcId(rpcId), status, response); } if (status != RpcStatus.SENT) { - log.debug("[{}][{}][{}][{}] Rpc was {}! Going to send next pending request ...", deviceId, sessionId, rpcId, requestId, status.name().toLowerCase()); + log.debug("[{}][{}][{}][{}] RPC was {}! Going to send next pending request ...", deviceId, sessionId, rpcId, requestId, status.name().toLowerCase()); sendNextPendingRequest(context); } } else { - log.warn("[{}][{}][{}][{}] Rpc has already been removed from pending map.", deviceId, sessionId, rpcId, requestId); + log.warn("[{}][{}][{}][{}] RPC has already been removed from pending map.", deviceId, sessionId, rpcId, requestId); } } @@ -693,7 +694,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso private void processSubscriptionCommands(TbActorCtx context, SessionInfoProto sessionInfo, SubscribeToRPCMsg subscribeCmd) { UUID sessionId = getSessionId(sessionInfo); if (subscribeCmd.getUnsubscribe()) { - log.debug("[{}] Canceling rpc subscription for session: [{}]", deviceId, sessionId); + log.debug("[{}] Canceling RPC subscription for session: [{}]", deviceId, sessionId); rpcSubscriptions.remove(sessionId); } else { SessionInfoMetaData sessionMD = sessions.get(sessionId); @@ -702,7 +703,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } sessionMD.setSubscribedToRPC(true); rpcSubscriptions.put(sessionId, sessionMD.getSessionInfo()); - log.debug("[{}] Registered rpc subscription for session: [{}] Going to check for pending requests ...", deviceId, sessionId); + log.debug("[{}] Registered RPC subscription for session: [{}] Going to check for pending requests ...", deviceId, sessionId); sendPendingRequests(context, sessionId, sessionInfo.getNodeId()); dumpSessions(); } @@ -945,14 +946,14 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } log.debug("[{}] Restored session: {}", deviceId, sessionMD); } - log.debug("[{}] Restored sessions: {}, rpc subscriptions: {}, attribute subscriptions: {}", deviceId, sessions.size(), rpcSubscriptions.size(), attributeSubscriptions.size()); + log.debug("[{}] Restored sessions: {}, RPC subscriptions: {}, attribute subscriptions: {}", deviceId, sessions.size(), rpcSubscriptions.size(), attributeSubscriptions.size()); } private void dumpSessions() { if (systemContext.isLocalCacheType()) { return; } - log.debug("[{}] Dumping sessions: {}, rpc subscriptions: {}, attribute subscriptions: {} to cache", deviceId, sessions.size(), rpcSubscriptions.size(), attributeSubscriptions.size()); + log.debug("[{}] Dumping sessions: {}, RPC subscriptions: {}, attribute subscriptions: {} to cache", deviceId, sessions.size(), rpcSubscriptions.size(), attributeSubscriptions.size()); List sessionsList = new ArrayList<>(sessions.size()); sessions.forEach((uuid, sessionMD) -> { if (sessionMD.getSessionInfo().getType() == SessionType.SYNC) { diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index efa5aee965..621504564f 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -207,7 +207,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement private void closeCtx(ChannelHandlerContext ctx) { if (!rpcAwaitingAck.isEmpty()) { - log.debug("[{}] Cleanup rpc awaiting ack map due to session close!", sessionId); + log.debug("[{}] Cleanup RPC awaiting ack map due to session close!", sessionId); rpcAwaitingAck.clear(); } ctx.close(); @@ -1229,7 +1229,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement @Override public void onToDeviceRpcRequest(UUID sessionId, TransportProtos.ToDeviceRpcRequestMsg rpcRequest) { - log.trace("[{}] Received RPC command to device", sessionId); + log.trace("[{}][{}] Received RPC command to device: {}", deviceSessionCtx.getDeviceId(), sessionId, rpcRequest); try { if (sparkplugSessionHandler != null) { handleToSparkplugDeviceRpcRequest(rpcRequest); @@ -1240,7 +1240,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement .ifPresent(payload -> sendToDeviceRpcRequest(payload, rpcRequest, deviceSessionCtx.getSessionInfo())); } } catch (Exception e) { - log.trace("[{}] Failed to convert device RPC command to MQTT msg", sessionId, e); + log.trace("[{}][{}] Failed to convert device RPC command to MQTT msg", deviceSessionCtx.getDeviceId(), sessionId, e); this.sendErrorRpcResponse(deviceSessionCtx.getSessionInfo(), rpcRequest.getRequestId(), ThingsboardErrorCode.INVALID_ARGUMENTS, "Failed to convert device RPC command to MQTT msg: " + rpcRequest.getMethodName() + rpcRequest.getParams()); @@ -1284,19 +1284,20 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement } var cf = publish(payload, deviceSessionCtx); cf.addListener(result -> { - if (result.cause() == null) { - if (!isAckExpected(payload)) { - transportService.process(sessionInfo, rpcRequest, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY); - } else if (rpcRequest.getPersisted()) { - transportService.process(sessionInfo, rpcRequest, RpcStatus.SENT, TransportServiceCallback.EMPTY); - } - if (sparkplugSessionHandler != null) { - this.sendSuccessRpcResponse(sessionInfo, rpcRequest.getRequestId(), ResponseCode.CONTENT, "Success: " + rpcRequest.getMethodName()); - } - } else { - log.trace("[{}] Failed send To Device Rpc Request [{}]", sessionId, rpcRequest.getMethodName()); + Throwable throwable = result.cause(); + if (throwable != null) { + log.trace("[{}][{}][{}] Failed send RPC request to device due to: ", deviceSessionCtx.getDeviceId(), sessionId, rpcRequest.getRequestId(), throwable); this.sendErrorRpcResponse(sessionInfo, rpcRequest.getRequestId(), ThingsboardErrorCode.INVALID_ARGUMENTS, " Failed send To Device Rpc Request: " + rpcRequest.getMethodName()); + return; + } + if (!isAckExpected(payload)) { + transportService.process(sessionInfo, rpcRequest, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY); + } else if (rpcRequest.getPersisted()) { + transportService.process(sessionInfo, rpcRequest, RpcStatus.SENT, TransportServiceCallback.EMPTY); + } + if (sparkplugSessionHandler != null) { + this.sendSuccessRpcResponse(sessionInfo, rpcRequest.getRequestId(), ResponseCode.CONTENT, "Success: " + rpcRequest.getMethodName()); } }); } From d992355a3ca57252111be48b5b3f1cc2093a3896 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 6 Jun 2023 17:20:35 +0300 Subject: [PATCH 134/207] UI: Implement basic config form for Entities table widget. --- .../json/system/widget_bundles/cards.json | 6 +- ui-ngx/src/app/core/http/entity.service.ts | 5 +- .../core/services/dashboard-utils.service.ts | 23 +-- .../add-widget-dialog.component.html | 1 + ...entities-table-basic-config.component.html | 24 +++ .../entities-table-basic-config.component.ts | 51 ++++- .../simple-card-basic-config.component.ts | 13 +- .../basic/common/data-key-row.component.html | 15 ++ .../basic/common/data-key-row.component.scss | 8 + .../basic/common/data-key-row.component.ts | 67 ++++++- .../common/data-keys-panel.component.html | 7 +- .../common/data-keys-panel.component.scss | 7 +- .../basic/common/data-keys-panel.component.ts | 13 +- .../common/widget-actions-panel.component.ts | 2 +- .../config/data-key-config.component.ts | 10 + .../widget/config/datasources.component.ts | 2 +- .../timewindow-config-panel.component.ts | 2 +- .../config/widget-config.component.models.ts | 58 +++++- .../widget/config/widget-config.scss | 175 ------------------ .../widget/config/widget-units.component.html | 2 +- .../widget/config/widget-units.component.ts | 3 +- .../simple-card-widget-settings.component.ts | 2 +- .../settings/common/value-source.component.ts | 2 +- .../device-key-autocomplete.component.ts | 11 +- .../image-map-provider-settings.component.ts | 2 +- .../widget/widget-config.component.ts | 21 ++- .../assets/locale/locale.constant-en_US.json | 2 + ui-ngx/src/styles.scss | 162 ++++++++++++++++ 28 files changed, 461 insertions(+), 235 deletions(-) delete mode 100644 ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss diff --git a/application/src/main/data/json/system/widget_bundles/cards.json b/application/src/main/data/json/system/widget_bundles/cards.json index 1cf107b801..9ab33665e6 100644 --- a/application/src/main/data/json/system/widget_bundles/cards.json +++ b/application/src/main/data/json/system/widget_bundles/cards.json @@ -104,7 +104,7 @@ "settingsDirective": "tb-simple-card-widget-settings", "hasBasicMode": true, "basicModeDirective": "tb-simple-card-basic-config", - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.2392660816082064,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#ff5722\",\"color\":\"rgba(255, 255, 255, 0.87)\",\"padding\":\"16px\",\"settings\":{\"labelPosition\":\"top\"},\"title\":\"Simple card\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"units\":\"°C\",\"decimals\":0,\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"configMode\":\"basic\"}" + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.2392660816082064,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#ff5722\",\"color\":\"rgba(255, 255, 255, 0.87)\",\"padding\":\"16px\",\"settings\":{\"labelPosition\":\"top\"},\"title\":\"Simple card\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"units\":\"°C\",\"decimals\":0,\"useDashboardTimewindow\":true,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"configMode\":\"basic\",\"displayTimewindow\":true}" } }, { @@ -143,7 +143,9 @@ "dataKeySettingsSchema": "", "settingsDirective": "tb-entities-table-widget-settings", "dataKeySettingsDirective": "tb-entities-table-key-settings", - "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"entitiesTitle\":\"\",\"enableSearch\":true,\"enableSelectColumnDisplay\":true,\"enableStickyHeader\":true,\"enableStickyAction\":true,\"reserveSpaceForHiddenAction\":\"true\",\"displayEntityName\":true,\"entityNameColumnTitle\":\"\",\"displayEntityLabel\":false,\"displayEntityType\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"entityName\",\"useRowStyleFunction\":false},\"title\":\"Entities table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"datasources\":[{\"type\":\"function\",\"name\":\"Simulated\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Sin\",\"color\":\"#2196f3\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.472295003170325,\"funcBody\":\"return Math.round(1000*Math.sin(time/5000));\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cos\",\"color\":\"#4caf50\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.8926244886945558,\"funcBody\":\"return Math.round(1000*Math.cos(time/5000));\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#f44336\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"useCellContentFunction\":false,\"defaultColumnVisibility\":\"visible\",\"columnSelectionToDisplay\":\"enabled\"},\"_hash\":0.6401141393938932,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}]}]}" + "hasBasicMode": true, + "basicModeDirective": "tb-entities-table-basic-config", + "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSearch\":true,\"enableSelectColumnDisplay\":true,\"enableStickyHeader\":true,\"enableStickyAction\":true,\"reserveSpaceForHiddenAction\":\"true\",\"displayEntityName\":false,\"displayEntityLabel\":false,\"displayEntityType\":false,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"name\",\"useRowStyleFunction\":false,\"entitiesTitle\":\"Entities\"},\"title\":\"Entities table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"datasources\":[{\"type\":\"function\",\"name\":\"Simulated\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Entity name\",\"color\":\"#2196f3\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.472295003170325,\"funcBody\":\"return 'Simulated';\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Entity type\",\"color\":\"#607d8b\",\"settings\":{},\"_hash\":0.782057645776538,\"funcBody\":\"return 'Device';\",\"decimals\":null,\"aggregationType\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Sin\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.904797781901171,\"funcBody\":\"return Math.round(1000*Math.sin(time/5000));\",\"decimals\":0},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cos\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.1961430898042078,\"funcBody\":\"return Math.round(1000*Math.cos(time/5000));\",\"decimals\":0},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.7678057538205878,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\",\"decimals\":2}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"displayTimewindow\":false,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"list\",\"iconColor\":null}" } }, { diff --git a/ui-ngx/src/app/core/http/entity.service.ts b/ui-ngx/src/app/core/http/entity.service.ts index ee3e232bba..12f6300b93 100644 --- a/ui-ngx/src/app/core/http/entity.service.ts +++ b/ui-ngx/src/app/core/http/entity.service.ts @@ -816,7 +816,8 @@ export class EntityService { ); } - public getEntityKeysByEntityFilter(filter: EntityFilter, types: DataKeyType[], config?: RequestConfig): Observable> { + public getEntityKeysByEntityFilter(filter: EntityFilter, types: DataKeyType[], + entityTypes?: EntityType[], config?: RequestConfig): Observable> { if (!types.length) { return of([]); } @@ -832,7 +833,7 @@ export class EntityService { entitiesKeysByQuery$ = of({ attribute: [], timeseries: [], - entityTypes: [], + entityTypes: entityTypes || [], }); } return entitiesKeysByQuery$.pipe( diff --git a/ui-ngx/src/app/core/services/dashboard-utils.service.ts b/ui-ngx/src/app/core/services/dashboard-utils.service.ts index 243c5e369b..8355ce2f61 100644 --- a/ui-ngx/src/app/core/services/dashboard-utils.service.ts +++ b/ui-ngx/src/app/core/services/dashboard-utils.service.ts @@ -366,25 +366,18 @@ export class DashboardUtilsService { } const dataKeys = newDatasource.dataKeys; newDatasource.dataKeys = []; - dataKeys.forEach(dataKey => { - newDatasource.dataKeys.push(this.convertDataKeyFromWidgetType(widgetTypeDescriptor, config, dataKey)); - }); + if (widgetTypeDescriptor.type === widgetType.alarm) { + dataKeys.forEach(dataKey => { + const newDataKey = deepClone(dataKey); + newDataKey.funcBody = null; + newDataKey.type = DataKeyType.alarm; + newDatasource.dataKeys.push(newDataKey); + }); + } } return newDatasource; } - private convertDataKeyFromWidgetType(widgetTypeDescriptor: WidgetTypeDescriptor, config: WidgetConfig, dataKey: DataKey): DataKey { - const newDataKey = deepClone(dataKey); - newDataKey.funcBody = null; - if (widgetTypeDescriptor.type === widgetType.alarm) { - newDataKey.type = DataKeyType.alarm; - } else { - newDataKey.type = DataKeyType.timeseries; - newDataKey.name = newDataKey.label; - } - return newDataKey; - } - private validateAndUpdateState(state: DashboardState) { if (!state.layouts) { state.layouts = this.createDefaultLayouts(); diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html b/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html index fb5336de66..5af51031bf 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html @@ -51,6 +51,7 @@ [widget]="widget" [widgetConfigMode]="widgetConfigMode" [hideHeader]="widgetConfigMode === widgetConfigModes.basic" + isAdd formControlName="widgetConfig">
widget-config.appearance
+
+ + {{ 'widget-config.card-title' | translate }} + + + + +
+
+ + {{ 'widget-config.card-icon' | translate }} + +
+ + + + + +
+
{{ 'widget-config.text-color' | translate }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts index 6ec1d6c5c4..4ddd068bb4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts @@ -26,11 +26,13 @@ import { datasourcesHasAggregation, datasourcesHasOnlyComparisonAggregation } from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; @Component({ selector: 'tb-entities-table-basic-config', templateUrl: './entities-table-basic-config.component.html', - styleUrls: ['../basic-config.scss', '../../widget-config.scss'] + styleUrls: ['../basic-config.scss'] }) export class EntitiesTableBasicConfigComponent extends BasicWidgetConfigComponent { @@ -56,14 +58,19 @@ export class EntitiesTableBasicConfigComponent extends BasicWidgetConfigComponen entitiesTableWidgetConfigForm: UntypedFormGroup; constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, private fb: UntypedFormBuilder) { - super(store); + super(store, widgetConfigComponent); } protected configForm(): UntypedFormGroup { return this.entitiesTableWidgetConfigForm; } + protected setupDefaults(configData: WidgetConfigComponentData) { + this.setupDefaultDatasource(configData, [{ name: 'name', type: DataKeyType.entityField }]); + } + protected onConfigSet(configData: WidgetConfigComponentData) { this.entitiesTableWidgetConfigForm = this.fb.group({ timewindowConfig: [{ @@ -73,6 +80,11 @@ export class EntitiesTableBasicConfigComponent extends BasicWidgetConfigComponen }, []], datasources: [configData.config.datasources, []], columns: [this.getColumns(configData.config.datasources), []], + showTitle: [configData.config.showTitle, []], + title: [configData.config.settings?.entitiesTitle, []], + showTitleIcon: [configData.config.showTitleIcon, []], + titleIcon: [configData.config.titleIcon, []], + iconColor: [configData.config.iconColor, []], color: [configData.config.color, []], backgroundColor: [configData.config.backgroundColor, []], actions: [configData.config.actions || {}, []] @@ -86,11 +98,46 @@ export class EntitiesTableBasicConfigComponent extends BasicWidgetConfigComponen this.widgetConfig.config.datasources = config.datasources; this.setColumns(config.columns, this.widgetConfig.config.datasources); this.widgetConfig.config.actions = config.actions; + this.widgetConfig.config.showTitle = config.showTitle; + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + this.widgetConfig.config.settings.entitiesTitle = config.title; + this.widgetConfig.config.showTitleIcon = config.showTitleIcon; + this.widgetConfig.config.titleIcon = config.titleIcon; + this.widgetConfig.config.iconColor = config.iconColor; this.widgetConfig.config.color = config.color; this.widgetConfig.config.backgroundColor = config.backgroundColor; return this.widgetConfig; } + protected validatorTriggers(): string[] { + return ['showTitle', 'showTitleIcon']; + } + + protected updateValidators(emitEvent: boolean, trigger?: string) { + const showTitle: boolean = this.entitiesTableWidgetConfigForm.get('showTitle').value; + const showTitleIcon: boolean = this.entitiesTableWidgetConfigForm.get('showTitleIcon').value; + if (showTitle) { + this.entitiesTableWidgetConfigForm.get('title').enable(); + this.entitiesTableWidgetConfigForm.get('showTitleIcon').enable({emitEvent: false}); + if (showTitleIcon) { + this.entitiesTableWidgetConfigForm.get('titleIcon').enable(); + this.entitiesTableWidgetConfigForm.get('iconColor').enable(); + } else { + this.entitiesTableWidgetConfigForm.get('titleIcon').disable(); + this.entitiesTableWidgetConfigForm.get('iconColor').disable(); + } + } else { + this.entitiesTableWidgetConfigForm.get('title').disable(); + this.entitiesTableWidgetConfigForm.get('showTitleIcon').disable({emitEvent: false}); + this.entitiesTableWidgetConfigForm.get('titleIcon').disable(); + this.entitiesTableWidgetConfigForm.get('iconColor').disable(); + } + this.entitiesTableWidgetConfigForm.get('title').updateValueAndValidity({emitEvent}); + this.entitiesTableWidgetConfigForm.get('showTitleIcon').updateValueAndValidity({emitEvent: false}); + this.entitiesTableWidgetConfigForm.get('titleIcon').updateValueAndValidity({emitEvent}); + this.entitiesTableWidgetConfigForm.get('iconColor').updateValueAndValidity({emitEvent}); + } + private getColumns(datasources?: Datasource[]): DataKey[] { if (datasources && datasources.length) { return datasources[0].dataKeys || []; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts index 62d25249e9..b59170fb89 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts @@ -23,13 +23,15 @@ import { WidgetConfigComponentData } from '@home/models/widget-component.models' import { Datasource, datasourcesHasAggregation, - datasourcesHasOnlyComparisonAggregation + datasourcesHasOnlyComparisonAggregation, } from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; @Component({ selector: 'tb-simple-card-basic-config', templateUrl: './simple-card-basic-config.component.html', - styleUrls: ['../basic-config.scss', '../../widget-config.scss'] + styleUrls: ['../basic-config.scss'] }) export class SimpleCardBasicConfigComponent extends BasicWidgetConfigComponent { @@ -46,14 +48,19 @@ export class SimpleCardBasicConfigComponent extends BasicWidgetConfigComponent { simpleCardWidgetConfigForm: UntypedFormGroup; constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, private fb: UntypedFormBuilder) { - super(store); + super(store, widgetConfigComponent); } protected configForm(): UntypedFormGroup { return this.simpleCardWidgetConfigForm; } + protected setupDefaults(configData: WidgetConfigComponentData) { + this.setupDefaultDatasource(configData, [{ name: 'temperature', label: 'Temperature', type: DataKeyType.timeseries }]); + } + protected onConfigSet(configData: WidgetConfigComponentData) { this.simpleCardWidgetConfigForm = this.fb.group({ timewindowConfig: [{ diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html index cf7b380650..0ae6ffb05e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html @@ -136,6 +136,21 @@ +
+ + +
+
+ + +
+
+ + + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss index a7165af95a..5b3d4f1a80 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss @@ -42,4 +42,12 @@ } } } + + .tb-color-field, .tb-units-field, .tb-decimals-field { + width: 60px; + display: flex; + flex-direction: row; + place-content: center; + align-items: center; + } } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts index 5664ec8d29..d434ef74e3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts @@ -37,7 +37,7 @@ import { } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; -import { DataKey, DatasourceType, JsonSettingsSchema, widgetType } from '@shared/models/widget.models'; +import { DataKey, DatasourceType, JsonSettingsSchema, Widget, widgetType } from '@shared/models/widget.models'; import { DataKeysPanelComponent } from '@home/components/widget/config/basic/common/data-keys-panel.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { AggregationType } from '@shared/models/time/time.models'; @@ -49,6 +49,13 @@ import { Observable, of } from 'rxjs'; import { filter, map, mergeMap, publishReplay, refCount, share, tap } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import { TruncatePipe } from '@shared/pipe/truncate.pipe'; +import { + DataKeyConfigDialogComponent, + DataKeyConfigDialogData +} from '@home/components/widget/config/data-key-config-dialog.component'; +import { deepClone } from '@core/utils'; +import { Dashboard } from '@shared/models/dashboard.models'; +import { IAliasController } from '@core/api/widget-api.models'; export const dataKeyRowValidator = (control: AbstractControl): ValidationErrors | null => { const dataKey: DataKey = control.value; @@ -63,7 +70,7 @@ export const dataKeyRowValidator = (control: AbstractControl): ValidationErrors @Component({ selector: 'tb-data-key-row', templateUrl: './data-key-row.component.html', - styleUrls: ['./data-key-row.component.scss', '../../data-keys.component.scss', '../../widget-config.scss'], + styleUrls: ['./data-key-row.component.scss', '../../data-keys.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -122,6 +129,10 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan return this.dataKeysPanelComponent.functionTypeKeys; } + get hideDataKeyColor(): boolean { + return this.dataKeysPanelComponent.hideDataKeyColor; + } + get widgetType(): widgetType { return this.widgetConfigComponent.widgetType; } @@ -130,14 +141,34 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan return this.widgetConfigComponent.widgetConfigCallbacks; } + get widget(): Widget { + return this.widgetConfigComponent.widget; + } + + get dashboard(): Dashboard { + return this.widgetConfigComponent.dashboard; + } + + get aliasController(): IAliasController { + return this.widgetConfigComponent.aliasController; + } + get datakeySettingsSchema(): JsonSettingsSchema { return this.widgetConfigComponent.modelValue?.dataKeySettingsSchema; } + get dataKeySettingsDirective(): string { + return this.widgetConfigComponent.modelValue?.dataKeySettingsDirective; + } + get isEntityDatasource(): boolean { return [DatasourceType.device, DatasourceType.entity].includes(this.datasourceType); } + get displayUnitsOrDigits() { + return this.modelValue.type && ![ DataKeyType.alarm, DataKeyType.entityField, DataKeyType.count ].includes(this.modelValue.type); + } + private propagateChange = (_val: any) => {}; constructor(private fb: UntypedFormBuilder, @@ -261,7 +292,37 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan } editKey() { - + this.dialog.open(DataKeyConfigDialogComponent, + { + disableClose: true, + panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], + data: { + dataKey: deepClone(this.modelValue), + dataKeySettingsSchema: this.datakeySettingsSchema, + dataKeySettingsDirective: this.dataKeySettingsDirective, + dashboard: this.dashboard, + aliasController: this.aliasController, + widget: this.widget, + widgetType: this.widgetType, + deviceId: this.deviceId, + entityAliasId: this.entityAliasId, + showPostProcessing: this.widgetType !== widgetType.alarm, + callbacks: this.callbacks, + hideDataKeyLabel: false, + hideDataKeyColor: this.hideDataKeyColor, + hideDataKeyUnits: !this.displayUnitsOrDigits, + hideDataKeyDecimals: !this.displayUnitsOrDigits + } + }).afterClosed().subscribe((updatedDataKey) => { + if (updatedDataKey) { + this.modelValue = updatedDataKey; + this.keyRowFormGroup.get('label').patchValue(this.modelValue.label, {emitEvent: false}); + this.keyRowFormGroup.get('color').patchValue(this.modelValue.color, {emitEvent: false}); + this.keyRowFormGroup.get('units').patchValue(this.modelValue.units, {emitEvent: false}); + this.keyRowFormGroup.get('decimals').patchValue(this.modelValue.decimals, {emitEvent: false}); + this.updateModel(); + } + }); } removeKey() { diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html index b4e8795f8f..754f0052c9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html @@ -21,9 +21,10 @@
datakey.key
datakey.label
-
datakey.color
-
widget-config.units-short
-
widget-config.decimals-short
+
datakey.color
+
widget-config.units-short
+
widget-config.decimals-short
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.scss index 944181f085..df8b187535 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.scss @@ -29,13 +29,18 @@ align-items: center; gap: 12px; padding-left: 12px; - padding-right: 12px; .tb-data-keys-header-cell { font-weight: 400; font-size: 14px; line-height: 20px; letter-spacing: 0.2px; color: rgba(0, 0, 0, 0.54); + &.tb-color-header, &.tb-units-header, &.tb-decimals-header { + width: 60px; + } + &.tb-actions-header { + width: 76px; + } } } .tb-data-keys-body { diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts index c27de8549b..3d8b80c1df 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts @@ -44,11 +44,12 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { alarmFields } from '@shared/models/alarm.models'; import { UtilsService } from '@core/services/utils.service'; import { DataKeysCallbacks } from '@home/components/widget/config/data-keys.component.models'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-data-keys-panel', templateUrl: './data-keys-panel.component.html', - styleUrls: ['./data-keys-panel.component.scss', '../../widget-config.scss'], + styleUrls: ['./data-keys-panel.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -89,6 +90,10 @@ export class DataKeysPanelComponent implements ControlValueAccessor, OnInit, OnC @Input() deviceId: string; + @Input() + @coerceBoolean() + hideDataKeyColor = false; + dataKeyType: DataKeyType; alarmKeys: Array; functionTypeKeys: Array; @@ -212,13 +217,11 @@ export class DataKeysPanelComponent implements ControlValueAccessor, OnInit, OnC addKey() { const dataKey = this.callbacks.generateDataKey('', null, this.datakeySettingsSchema); + dataKey.label = ''; + dataKey.decimals = 0; const keysArray = this.keysListFormGroup.get('keys') as UntypedFormArray; const keyControl = this.fb.control(dataKey, [dataKeyRowValidator]); keysArray.push(keyControl); - this.keysListFormGroup.updateValueAndValidity(); - if (!this.keysListFormGroup.valid) { - this.propagateChange(this.keysListFormGroup.get('keys').value); - } } private prepareKeysFormArray(keys: DataKey[] | undefined): UntypedFormArray { diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts index 68dfca5858..469ff191ed 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts @@ -29,7 +29,7 @@ import { MatDialog } from '@angular/material/dialog'; @Component({ selector: 'tb-widget-actions-panel', templateUrl: './widget-actions-panel.component.html', - styleUrls: ['../../widget-config.scss'], + styleUrls: [], providers: [ { provide: NG_VALUE_ACCESSOR, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts index 9d9201e88a..a7cf923c44 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts @@ -155,6 +155,7 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con private dataKeySettingsData: JsonFormComponentData; private alarmKeys: Array; + private functionTypeKeys: Array; filteredKeys: Observable>; private latestKeySearchResult: Array = null; @@ -183,6 +184,13 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con type: DataKeyType.alarm }); } + this.functionTypeKeys = []; + for (const type of this.utils.getPredefinedFunctionsList()) { + this.functionTypeKeys.push({ + name: type, + type: DataKeyType.function + }); + } if (this.dataKeySettingsSchema && this.dataKeySettingsSchema.schema || this.dataKeySettingsDirective && this.dataKeySettingsDirective.length) { this.displayAdvanced = true; @@ -396,6 +404,8 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con let fetchObservable: Observable>; if (this.modelValue.type === DataKeyType.alarm) { fetchObservable = of(this.alarmKeys); + } else if (this.modelValue.type === DataKeyType.function) { + fetchObservable = of(this.functionTypeKeys); } else { if (this.deviceId || this.entityAliasId) { const dataKeyTypes = [this.modelValue.type]; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts index e94a3062e7..ae674a4d55 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts @@ -46,7 +46,7 @@ import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-datasources', templateUrl: './datasources.component.html', - styleUrls: ['./datasources.component.scss', './widget-config.scss'], + styleUrls: ['./datasources.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts index ec7e8d0854..31436c9415 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts @@ -31,7 +31,7 @@ export interface TimewindowConfigData { @Component({ selector: 'tb-timewindow-config-panel', templateUrl: './timewindow-config-panel.component.html', - styleUrls: ['./widget-config.scss'], + styleUrls: [], providers: [ { provide: NG_VALUE_ACCESSOR, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts index 39b3c2a741..9bda9345dc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts @@ -23,12 +23,15 @@ import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { AbstractControl, UntypedFormGroup } from '@angular/forms'; -import { WidgetConfigMode } from '@shared/models/widget.models'; +import { DataKey, DatasourceType, KeyInfo, WidgetConfigMode } from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { isDefinedAndNotNull } from '@core/utils'; export type WidgetConfigCallbacks = DatasourceCallbacks & WidgetActionCallbacks; export interface IBasicWidgetConfigComponent { - + isAdd: boolean; widgetConfig: WidgetConfigComponentData; widgetConfigChanged: Observable; validateConfig(): boolean; @@ -40,6 +43,8 @@ export interface IBasicWidgetConfigComponent { export abstract class BasicWidgetConfigComponent extends PageComponent implements IBasicWidgetConfigComponent, OnInit, AfterViewInit { + isAdd = false; + basicMode = WidgetConfigMode.basic; widgetConfigValue: WidgetConfigComponentData; @@ -56,7 +61,8 @@ export abstract class BasicWidgetConfigComponent extends PageComponent implement widgetConfigChangedEmitter = new EventEmitter(); widgetConfigChanged = this.widgetConfigChangedEmitter.asObservable(); - protected constructor(@Inject(Store) protected store: Store) { + protected constructor(@Inject(Store) protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent) { super(store); } @@ -65,12 +71,15 @@ export abstract class BasicWidgetConfigComponent extends PageComponent implement ngAfterViewInit(): void { setTimeout(() => { if (!this.validateConfig()) { - this.onConfigChanged(this.prepareOutputConfig(this.configForm().value)); + this.onConfigChanged(this.prepareOutputConfig(this.configForm().getRawValue())); } }, 0); } protected setupConfig(widgetConfig: WidgetConfigComponentData) { + if (this.isAdd) { + this.setupDefaults(widgetConfig); + } this.onConfigSet(widgetConfig); this.updateValidators(false); for (const trigger of this.validatorTriggers()) { @@ -83,11 +92,13 @@ export abstract class BasicWidgetConfigComponent extends PageComponent implement this.updateValidators(true, trigger); }); } - this.configForm().valueChanges.subscribe((updated: any) => { - this.onConfigChanged(this.prepareOutputConfig(updated)); + this.configForm().valueChanges.subscribe(() => { + this.onConfigChanged(this.prepareOutputConfig(this.configForm().getRawValue())); }); } + protected setupDefaults(configData: WidgetConfigComponentData) {} + protected updateValidators(emitEvent: boolean, trigger?: string) { } @@ -108,6 +119,41 @@ export abstract class BasicWidgetConfigComponent extends PageComponent implement return this.configForm().valid; } + protected setupDefaultDatasource(configData: WidgetConfigComponentData, keys?: DataKey[]) { + let datasources = configData.config.datasources; + if (!datasources || !datasources.length) { + datasources = [ + { + type: DatasourceType.device, + dataKeys: [] + } + ]; + configData.config.datasources = datasources; + } + let dataKeys = datasources[0].dataKeys; + if (!dataKeys) { + dataKeys = []; + datasources[0].dataKeys = dataKeys; + } + if (keys && keys.length) { + dataKeys.length = 0; + keys.forEach(key => { + const dataKey = + this.widgetConfigComponent.widgetConfigCallbacks.generateDataKey(key.name, key.type, configData.dataKeySettingsSchema); + if (key.label) { + dataKey.label = key.label; + } + if (key.units) { + dataKey.units = key.units; + } + if (isDefinedAndNotNull(key.decimals)) { + dataKey.decimals = key.decimals; + } + dataKeys.push(dataKey); + }); + } + } + protected abstract configForm(): UntypedFormGroup; protected abstract onConfigSet(configData: WidgetConfigComponentData); diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss deleted file mode 100644 index 754afcf1d1..0000000000 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss +++ /dev/null @@ -1,175 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -.tb-widget-config-panel { - box-shadow: 0 0 10px 6px rgba(11, 17, 51, 0.04); - border-radius: 4px; - padding: 16px; - gap: 16px; - display: flex; - flex-direction: column; - color: rgba(0, 0, 0, 0.87); - letter-spacing: 0.15px; - position: relative; - &.no-padding-bottom { - padding-bottom: 0; - } - &.stroked { - box-shadow: none; - border: 1px solid rgba(0, 0, 0, 0.12); - border-radius: 6px; - } -} -.tb-widget-config-panel-title { - font-weight: 500; - font-size: 16px; -} -.tb-widget-config-panel-hint { - font-size: 12px; - color: #808080; -} -.tb-widget-config-row { - height: 56px; - display: flex; - flex-direction: row; - align-items: center; - gap: 16px; - padding-left: 16px; - padding-right: 12px; - border: 1px solid rgba(0, 0, 0, 0.12); - border-radius: 6px; - &.same-padding { - padding-right: 16px; - } - &.space-between { - justify-content: space-between; - } - .mat-divider-vertical { - height: 56px; - } -} - -.tb-widget-config-row .mat-mdc-form-field, .mat-mdc-form-field.tb-inline-field { - &.mat-form-field-appearance-fill { - .mdc-text-field--filled:not(.mdc-text-field--disabled):before { - opacity: 0; - } - .mat-mdc-form-field-focus-overlay { - opacity: 0; - } - } - .mat-mdc-text-field-wrapper { - &.mdc-text-field--outlined, &:not(.mdc-text-field--outlined) { - padding-right: 12px; - padding-left: 12px; - &:not(.mdc-text-field--focused):not(.mdc-text-field--disabled):not(:hover) { - .mdc-notched-outline__leading, .mdc-notched-outline__trailing { - border-color: rgba(0, 0, 0, 0.12); - } - } - .mat-mdc-form-field-infix { - padding-top: 7px; - padding-bottom: 7px; - min-height: 38px; - width: 72px; - } - } - } - &.center { - .mat-mdc-text-field-wrapper { - .mat-mdc-form-field-infix { - .mdc-text-field__input { - text-align: center; - } - } - } - } - &.number { - .mat-mdc-text-field-wrapper { - padding-right: 4px; - .mat-mdc-form-field-infix { - width: 80px; - input.mdc-text-field__input[type=number]::-webkit-inner-spin-button, - input.mdc-text-field__input[type=number]::-webkit-outer-spin-button { - opacity: 1; - } - } - } - } -} - - -:host ::ng-deep { - - .mat-slide { - margin: 8px 0; - .mdc-form-field>label { - font-weight: 400; - font-size: 16px; - line-height: 24px; - margin-left: 12px; - } - } - - .slide-block { - display: block; - &:not(:last-child) { - margin-bottom: 8px; - } - } - - .tb-widget-config-panel { - .mat-expansion-panel { - &.tb-settings { - box-shadow: none; - .mat-content { - overflow: visible; - } - .mat-expansion-panel-header { - font-weight: 500; - font-size: 16px; - line-height: 24px; - letter-spacing: 0.25px; - padding: 0; - .mat-content { - flex: 0; - white-space: nowrap; - } - &:hover { - background: none; - } - .mat-expansion-indicator { - height: 32px; - padding: 2px; - } - } - .mat-expansion-panel-header-description { - align-items: center; - } - > .mat-expansion-panel-content { - > .mat-expansion-panel-body { - padding: 0; - } - } - .tb-json-object-panel, .tb-css-content-panel { - margin: 0 0 8px; - } - } - .mat-expansion-panel-content { - font: inherit; - } - } - } -} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html index d573e65183..a2ed480388 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html @@ -15,6 +15,6 @@ limitations under the License. --> - + diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.ts index 4a1665b5b2..e61511698d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.ts @@ -20,7 +20,7 @@ import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR, UntypedFormBuilde @Component({ selector: 'tb-widget-units', templateUrl: './widget-units.component.html', - styleUrls: ['./widget-config.scss'], + styleUrls: [], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -43,6 +43,7 @@ export class WidgetUnitsComponent implements ControlValueAccessor, OnInit { ngOnInit() { this.unitsFormControl = this.fb.control('', []); + this.unitsFormControl.valueChanges.subscribe(val => this.propagateChange(val)); } writeValue(units?: string): void { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts index b9080b93ff..4ecd21ad1d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/simple-card-widget-settings.component.ts @@ -23,7 +23,7 @@ import { AppState } from '@core/core.state'; @Component({ selector: 'tb-simple-card-widget-settings', templateUrl: './simple-card-widget-settings.component.html', - styleUrls: ['../../../config/widget-config.scss'] + styleUrls: [] }) export class SimpleCardWidgetSettingsComponent extends WidgetSettingsComponent { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source.component.ts index d3858b89f6..6417ae4bcb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/value-source.component.ts @@ -215,7 +215,7 @@ export class ValueSourceComponent extends PageComponent implements OnInit, Contr mergeMap((aliasInfo) => { return this.entityService.getEntityKeysByEntityFilter( aliasInfo.entityFilter, - dataKeyTypes, + dataKeyTypes, [], {ignoreLoading: true, ignoreErrors: true} ).pipe( catchError(() => of([])) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.ts index 2ada7e6cfb..22f8bf8e75 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.ts @@ -15,7 +15,13 @@ /// import { Component, ElementRef, forwardRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core'; -import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormGroup, + Validators +} from '@angular/forms'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -27,6 +33,7 @@ import { catchError, map, mergeMap, publishReplay, refCount, tap } from 'rxjs/op import { DataKey } from '@shared/models/widget.models'; import { EntityService } from '@core/http/entity.service'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; +import { EntityType } from '@shared/models/entity-type.models'; @Component({ selector: 'tb-device-key-autocomplete', @@ -199,7 +206,7 @@ export class DeviceKeyAutocompleteComponent extends PageComponent implements OnI mergeMap((aliasInfo) => { return this.entityService.getEntityKeysByEntityFilter( aliasInfo.entityFilter, - dataKeyTypes, + dataKeyTypes, [EntityType.DEVICE], {ignoreLoading: true, ignoreErrors: true} ).pipe( catchError(() => of([])) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/image-map-provider-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/image-map-provider-settings.component.ts index 7e96d6ba0a..e79735e70d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/image-map-provider-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/map/image-map-provider-settings.component.ts @@ -236,7 +236,7 @@ export class ImageMapProviderSettingsComponent extends PageComponent implements mergeMap((aliasInfo) => { return this.entityService.getEntityKeysByEntityFilter( aliasInfo.entityFilter, - dataKeyTypes, + dataKeyTypes, [], {ignoreLoading: true, ignoreErrors: true} ).pipe( catchError(() => of([])) diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index 744747a50a..999e7e55ff 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -81,8 +81,8 @@ import { FilterDialogComponent, FilterDialogData } from '@home/components/filter import { ToggleHeaderOption } from '@shared/components/toggle-header.component'; import { coerceBoolean } from '@shared/decorators/coercion'; import { basicWidgetConfigComponentsMap } from '@home/components/widget/config/basic/basic-widget-config.module'; -import Timeout = NodeJS.Timeout; import { TimewindowConfigData } from '@home/components/widget/config/timewindow-config-panel.component'; +import Timeout = NodeJS.Timeout; const emptySettingsSchema: JsonSchema = { type: 'object', @@ -96,7 +96,7 @@ const defaultSettingsForm = [ @Component({ selector: 'tb-widget-config', templateUrl: './widget-config.component.html', - styleUrls: ['./widget-config.component.scss', './config/widget-config.scss'], + styleUrls: ['./widget-config.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -143,6 +143,10 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe @coerceBoolean() hideToggleHeader = false; + @Input() + @coerceBoolean() + isAdd = false; + @Input() disabled: boolean; @Input() @@ -399,22 +403,22 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe writeValue(value: WidgetConfigComponentData): void { this.modelValue = value; this.widgetType = this.modelValue?.widgetType; - this.setupConfig(); + this.setupConfig(this.isAdd); } - private setupConfig() { + private setupConfig(isAdd = false) { if (this.modelValue) { this.destroyBasicModeComponent(); this.removeChangeSubscriptions(); if (this.hasBasicModeDirective && this.widgetConfigMode === WidgetConfigMode.basic) { - this.setupBasicModeConfig(); + this.setupBasicModeConfig(isAdd); } else { this.setupDefaultConfig(); } } } - private setupBasicModeConfig() { + private setupBasicModeConfig(isAdd = false) { const componentType = basicWidgetConfigComponentsMap[this.modelValue.basicModeDirective]; if (!componentType) { this.basicModeDirectiveError = this.translate.instant('widget-config.settings-component-not-found', @@ -425,6 +429,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.createBasicModeComponentTimeout = null; this.basicModeComponentRef = this.basicModeContainer.createComponent(factory); this.basicModeComponent = this.basicModeComponentRef.instance; + this.basicModeComponent.isAdd = isAdd; this.basicModeComponent.widgetConfig = this.modelValue; this.basicModeComponentChangeSubscription = this.basicModeComponent.widgetConfigChanged.subscribe((data) => { this.modelValue = data; @@ -826,7 +831,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe const entityFilter = singleEntityFilterFromDeviceId(deviceId); return this.entityService.getEntityKeysByEntityFilter( entityFilter, - dataKeyTypes, + dataKeyTypes, [EntityType.DEVICE], {ignoreLoading: true, ignoreErrors: true} ).pipe( catchError(() => of([])) @@ -837,7 +842,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe return this.aliasController.getAliasInfo(entityAliasId).pipe( mergeMap((aliasInfo) => this.entityService.getEntityKeysByEntityFilter( aliasInfo.entityFilter, - dataKeyTypes, + dataKeyTypes, [], {ignoreLoading: true, ignoreErrors: true} ).pipe( catchError(() => of([])) 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 bc14e58e98..b6f6bd8386 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4125,6 +4125,7 @@ "title-tooltip": "Title Tooltip", "general-settings": "General settings", "display-title": "Display widget title", + "card-title": "Card title", "drop-shadow": "Drop shadow", "enable-fullscreen": "Enable fullscreen", "background-color": "Background color", @@ -4179,6 +4180,7 @@ "delete-action-text": "Are you sure you want delete widget action with name '{{actionName}}'?", "title-icon": "Title icon", "display-icon": "Display title icon", + "card-icon": "Card icon", "icon-color": "Icon color", "icon-size": "Icon size", "advanced-settings": "Advanced settings", diff --git a/ui-ngx/src/styles.scss b/ui-ngx/src/styles.scss index 3d4029d564..760ffe88c6 100644 --- a/ui-ngx/src/styles.scss +++ b/ui-ngx/src/styles.scss @@ -1183,4 +1183,166 @@ mat-label { .mat-expansion-panel { color: inherit; } + + // Widget config + + .tb-widget-config-panel { + box-shadow: 0 0 10px 6px rgba(11, 17, 51, 0.04); + border-radius: 4px; + padding: 16px; + gap: 16px; + display: flex; + flex-direction: column; + color: rgba(0, 0, 0, 0.87); + letter-spacing: 0.15px; + position: relative; + &.no-padding-bottom { + padding-bottom: 0; + } + &.stroked { + box-shadow: none; + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 6px; + } + .mat-expansion-panel { + &.tb-settings { + box-shadow: none; + .mat-content { + overflow: visible; + } + .mat-expansion-panel-header { + font-weight: 500; + font-size: 16px; + line-height: 24px; + letter-spacing: 0.25px; + padding: 0; + .mat-content { + flex: 0; + white-space: nowrap; + } + &:hover { + background: none; + } + .mat-expansion-indicator { + height: 32px; + padding: 2px; + } + } + .mat-expansion-panel-header-description { + align-items: center; + } + > .mat-expansion-panel-content { + > .mat-expansion-panel-body { + padding: 0; + } + } + .tb-json-object-panel, .tb-css-content-panel { + margin: 0 0 8px; + } + } + .mat-expansion-panel-content { + font: inherit; + } + } + .mat-slide { + margin: 8px 0; + .mdc-form-field>label { + font-weight: 400; + font-size: 16px; + line-height: 24px; + margin-left: 12px; + } + } + } + + .tb-widget-config-panel-title { + font-weight: 500; + font-size: 16px; + } + .tb-widget-config-panel-hint { + font-size: 12px; + color: #808080; + } + .tb-widget-config-row { + height: 56px; + display: flex; + flex-direction: row; + align-items: center; + gap: 16px; + padding-left: 16px; + padding-right: 12px; + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 6px; + &.same-padding { + padding-right: 16px; + } + &.space-between { + justify-content: space-between; + } + .mat-divider-vertical { + height: 56px; + } + .mat-mdc-form-field { + width: 80px; + } + } + + .tb-widget-config-row .mat-mdc-form-field, .mat-mdc-form-field.tb-inline-field { + &.mat-form-field-appearance-fill { + .mdc-text-field--filled:not(.mdc-text-field--disabled) { + &:before { + opacity: 0; + } + .mdc-line-ripple::before { + border-bottom-color: rgba(0, 0, 0, 0.12); + } + } + .mat-mdc-form-field-focus-overlay { + opacity: 0; + } + } + .mat-mdc-text-field-wrapper { + &.mdc-text-field--outlined, &:not(.mdc-text-field--outlined) { + padding-right: 12px; + padding-left: 12px; + &:not(.mdc-text-field--focused):not(.mdc-text-field--disabled):not(:hover) { + .mdc-notched-outline__leading, .mdc-notched-outline__trailing { + border-color: rgba(0, 0, 0, 0.12); + } + } + .mat-mdc-form-field-infix { + padding-top: 7px; + padding-bottom: 7px; + min-height: 38px; + width: auto; + .mdc-text-field__input, .mat-mdc-select { + font-weight: 400; + font-size: 14px; + line-height: 20px; + } + } + } + } + &.center { + .mat-mdc-text-field-wrapper { + .mat-mdc-form-field-infix { + .mdc-text-field__input { + text-align: center; + } + } + } + } + &.number { + .mat-mdc-text-field-wrapper { + padding-right: 4px; + .mat-mdc-form-field-infix { + input.mdc-text-field__input[type=number]::-webkit-inner-spin-button, + input.mdc-text-field__input[type=number]::-webkit-outer-spin-button { + opacity: 1; + } + } + } + } + } + } From f356a94b817027c09a93ae7696aaf13bddf5dba5 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 7 Jun 2023 00:06:55 +0300 Subject: [PATCH 135/207] added new hash_code column to resource table --- .../main/data/upgrade/3.5.1/schema_update.sql | 7 ++ .../controller/TbResourceController.java | 87 +++++++++++++------ .../resource/DefaultTbResourceService.java | 5 ++ .../server/common/data/ResourceType.java | 13 ++- .../server/common/data/TbResource.java | 2 + .../server/common/data/TbResourceInfo.java | 5 ++ .../server/dao/model/ModelConstants.java | 1 + .../dao/model/sql/TbResourceEntity.java | 6 ++ 8 files changed, 97 insertions(+), 29 deletions(-) diff --git a/application/src/main/data/upgrade/3.5.1/schema_update.sql b/application/src/main/data/upgrade/3.5.1/schema_update.sql index 3bc2c99168..9000acc69e 100644 --- a/application/src/main/data/upgrade/3.5.1/schema_update.sql +++ b/application/src/main/data/upgrade/3.5.1/schema_update.sql @@ -52,3 +52,10 @@ $$ $$; -- NOTIFICATION CONFIGS VERSION CONTROL END + +ALTER TABLE resource + ADD COLUMN IF NOT EXISTS hash_code varchar; + +UPDATE resource + SET hash_code = encode(sha256(decode(resource.data, 'base64')),'hex') WHERE resource.data is not null; + diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index d9c846e4bd..59d07c4781 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -22,6 +22,7 @@ import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.CacheControl; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -29,6 +30,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -47,10 +49,10 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.resource.TbResourceService; +import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import javax.servlet.http.HttpServletRequest; import java.util.Base64; import java.util.List; @@ -89,45 +91,47 @@ public class TbResourceController extends BaseController { @RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET) @ResponseBody public ResponseEntity downloadResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, HttpServletRequest request) throws ThingsboardException { + @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); TbResource tbResource = checkResourceId(resourceId, Operation.READ); ByteArrayResource resource = new ByteArrayResource(Base64.getDecoder().decode(tbResource.getData().getBytes())); - - HashCode hashCode = Hashing.sha256().hashBytes(resource.getByteArray()); - String ifNoneMatch = request.getHeader("If-None-Match"); - if (ifNoneMatch != null) { - if (ifNoneMatch.equals(hashCode.toString())) { - return ResponseEntity.status(HttpStatus.NOT_MODIFIED) - .eTag(hashCode.toString()).build(); - } - } - - String mediaType; - switch (tbResource.getResourceType()) { - case LWM2M_MODEL: - mediaType = "application/xml"; - break; - case JKS: - mediaType = "application/x-java-keystore"; - break; - case PKCS_12: - mediaType = "application/x-pkcs12"; - break; - default: mediaType = MediaType.APPLICATION_OCTET_STREAM_VALUE; - } - return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + tbResource.getFileName()) .header("x-filename", tbResource.getFileName()) .contentLength(resource.contentLength()) - .header("Content-Type", mediaType) - .eTag(hashCode.toString()) + .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(resource); } + @ApiOperation(value = "Download Resource (downloadResource)", notes = "Download Resource based on the provided Resource Id." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(value = "/resource/lwm2m/{resourceId}/download", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity downloadLwm2mResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader HttpHeaders headers) throws ThingsboardException { + return downloadResourceIfChanged(ResourceType.LWM2M_MODEL, strResourceId, headers); + } + + @ApiOperation(value = "Download Resource (downloadResource)", notes = "Download Resource based on the provided Resource Id." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(value = "/resource/pkcs12/{resourceId}/download", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity downloadPkcs12ResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + @PathVariable(RESOURCE_ID) String strResourceId, HttpHeaders headers) throws ThingsboardException { + return downloadResourceIfChanged(ResourceType.PKCS_12, strResourceId, headers); + } + + @ApiOperation(value = "Download Resource (downloadResource)", notes = "Download Resource based on the provided Resource Id." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(value = "/resource/js/{resourceId}/download", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity downloadJsResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + @PathVariable(RESOURCE_ID) String strResourceId, HttpHeaders headers) throws ThingsboardException { + return downloadResourceIfChanged(ResourceType.JS_MODULE, strResourceId, headers); + } + @ApiOperation(value = "Get Resource Info (getResourceInfoById)", notes = "Fetch the Resource Info object based on the provided Resource Id. " + RESOURCE_INFO_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, @@ -257,4 +261,31 @@ public class TbResourceController extends BaseController { TbResource tbResource = checkResourceId(resourceId, Operation.DELETE); tbResourceService.delete(tbResource, getCurrentUser()); } + + private ResponseEntity downloadResourceIfChanged(ResourceType type, String strResourceId, HttpHeaders headers) throws ThingsboardException { + checkParameter(RESOURCE_ID, strResourceId); + TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); + TbResourceInfo tbResourceInfo = checkResourceInfoId(resourceId, Operation.READ); + + List ifNoneMatchHeaders = headers.getIfNoneMatch(); + if (!ifNoneMatchHeaders.isEmpty()) { + if (ifNoneMatchHeaders.contains(tbResourceInfo.getHashCode())) { + return ResponseEntity.status(HttpStatus.NOT_MODIFIED) + .eTag(tbResourceInfo.getHashCode()).build(); + } + } + + SecurityUser currentUser = getCurrentUser(); + TbResource tbResource = resourceService.findResourceById(currentUser.getTenantId(), resourceId); + ByteArrayResource resource = new ByteArrayResource(Base64.getDecoder().decode(tbResource.getData().getBytes())); + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + tbResource.getFileName()) + .header("x-filename", tbResource.getFileName()) + .contentLength(resource.contentLength()) + .header("Content-Type", type.mediaType) + .cacheControl(CacheControl.noCache()) + .eTag(tbResource.getHashCode()) + .body(resource); + } } \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java index e8b90c02d7..97eac85c48 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.service.resource; +import com.google.common.hash.HashCode; +import com.google.common.hash.Hashing; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.EntityType; @@ -36,6 +38,7 @@ import org.thingsboard.server.dao.resource.ResourceService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; +import java.util.Base64; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -166,6 +169,8 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements } else { resource.setResourceKey(resource.getFileName()); } + HashCode hashCode = Hashing.sha256().hashBytes(Base64.getDecoder().decode(resource.getData().getBytes())); + resource.setHashCode(hashCode.toString()); return resourceService.saveResource(resource); } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java index a9c34a3903..bef4681c05 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java @@ -16,5 +16,16 @@ package org.thingsboard.server.common.data; public enum ResourceType { - LWM2M_MODEL, JKS, PKCS_12, JS_MODULE + LWM2M_MODEL("lwm2m", "application/xml"), + JKS("jks", "application/x-java-keystore"), + PKCS_12("pkcs12", "application/x-pkcs12"), + JS_MODULE("js", "application/javascript"); + + public String type; + public String mediaType; + + ResourceType(String type, String mediaType) { + this.type = type; + this.mediaType = mediaType; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java index 91bb7ba383..1d6f7ca21d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java @@ -74,6 +74,8 @@ public class TbResource extends TbResourceInfo { builder.append(fileName); builder.append(", data="); builder.append(data); + builder.append(", hashCode="); + builder.append(getHashCode()); builder.append("]"); return builder.toString(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java index 331958ac58..671cd65924 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java @@ -48,6 +48,8 @@ public class TbResourceInfo extends BaseData implements HasName, H private String resourceKey; @ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String searchText; + @ApiModelProperty(position = 8, value = "Resource hash code.", example = "33a64df551425fcc55e4d42a148795d9f25f89d4", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + private String hashCode; public TbResourceInfo() { super(); @@ -64,6 +66,7 @@ public class TbResourceInfo extends BaseData implements HasName, H this.resourceType = resourceInfo.getResourceType(); this.resourceKey = resourceInfo.getResourceKey(); this.searchText = resourceInfo.getSearchText(); + this.hashCode = resourceInfo.getHashCode(); } @ApiModelProperty(position = 1, value = "JSON object with the Resource Id. " + @@ -107,6 +110,8 @@ public class TbResourceInfo extends BaseData implements HasName, H builder.append(resourceType); builder.append(", resourceKey="); builder.append(resourceKey); + builder.append(", hashCode="); + builder.append(hashCode); builder.append("]"); return builder.toString(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 17606e1a1f..68123b22c4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -480,6 +480,7 @@ public class ModelConstants { public static final String RESOURCE_TITLE_COLUMN = TITLE_PROPERTY; public static final String RESOURCE_FILE_NAME_COLUMN = "file_name"; public static final String RESOURCE_DATA_COLUMN = "data"; + public static final String RESOURCE_HASH_CODE_COLUMN = "hash_code"; /** * Ota Package constants. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java index 1540abfe6b..bfd26a6290 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java @@ -31,6 +31,7 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_DATA_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_FILE_NAME_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_HASH_CODE_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_KEY_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TENANT_ID_COLUMN; @@ -65,6 +66,9 @@ public class TbResourceEntity extends BaseSqlEntity implements BaseE @Column(name = RESOURCE_DATA_COLUMN) private String data; + @Column(name = RESOURCE_HASH_CODE_COLUMN) + private String hashCode; + public TbResourceEntity() { } @@ -82,6 +86,7 @@ public class TbResourceEntity extends BaseSqlEntity implements BaseE this.searchText = resource.getSearchText(); this.fileName = resource.getFileName(); this.data = resource.getData(); + this.hashCode = resource.getHashCode(); } @Override @@ -95,6 +100,7 @@ public class TbResourceEntity extends BaseSqlEntity implements BaseE resource.setSearchText(searchText); resource.setFileName(fileName); resource.setData(data); + resource.setHashCode(hashCode); return resource; } From 29384170d79b988dcefef38938f4fc954a28590c Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 7 Jun 2023 13:16:55 +0300 Subject: [PATCH 136/207] added tests --- .../controller/ControllerConstants.java | 2 +- .../controller/TbResourceController.java | 8 +- .../server/controller/AbstractWebTest.java | 7 ++ .../controller/TbResourceControllerTest.java | 112 ++++++++++++++++-- .../server/common/data/ResourceType.java | 21 +++- .../dao/model/sql/TbResourceInfoEntity.java | 6 + .../main/resources/sql/schema-entities.sql | 1 + 7 files changed, 137 insertions(+), 20 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index 1cb794c2ec..a8cc2c1043 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java @@ -140,7 +140,7 @@ public class ControllerConstants { protected static final String RESOURCE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the resource title."; protected static final String RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, resourceType, tenantId"; - protected static final String RESOURCE_TYPE_PROPERTY_ALLOWABLE_VALUES = "LWM2M_MODEL, JKS, PKCS_12, JS_MODULE"; + protected static final String RESOURCE_TYPE_PROPERTY_ALLOWABLE_VALUES = "lwm2m, jks, pkcs12, js"; protected static final String RESOURCE_TYPE = "A string value representing the resource type."; protected static final String LWM2M_OBJECT_DESCRIPTION = "LwM2M Object is a object that includes information about the LwM2M model which can be used in transport configuration for the LwM2M device profile. "; diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index 59d07c4781..369dc2e2bd 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -119,7 +119,7 @@ public class TbResourceController extends BaseController { @RequestMapping(value = "/resource/pkcs12/{resourceId}/download", method = RequestMethod.GET) @ResponseBody public ResponseEntity downloadPkcs12ResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, HttpHeaders headers) throws ThingsboardException { + @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader HttpHeaders headers) throws ThingsboardException { return downloadResourceIfChanged(ResourceType.PKCS_12, strResourceId, headers); } @@ -128,7 +128,7 @@ public class TbResourceController extends BaseController { @RequestMapping(value = "/resource/js/{resourceId}/download", method = RequestMethod.GET) @ResponseBody public ResponseEntity downloadJsResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, HttpHeaders headers) throws ThingsboardException { + @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader HttpHeaders headers) throws ThingsboardException { return downloadResourceIfChanged(ResourceType.JS_MODULE, strResourceId, headers); } @@ -203,7 +203,7 @@ public class TbResourceController extends BaseController { TbResourceInfoFilter.TbResourceInfoFilterBuilder filter = TbResourceInfoFilter.builder(); filter.tenantId(getTenantId()); if (StringUtils.isNotEmpty(resourceType)){ - filter.resourceType(ResourceType.valueOf(resourceType)); + filter.resourceType(ResourceType.getResourceByType(resourceType)); } if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { return checkNotNull(resourceService.findTenantResourcesByTenantId(filter.build(), pageLink)); @@ -283,7 +283,7 @@ public class TbResourceController extends BaseController { .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + tbResource.getFileName()) .header("x-filename", tbResource.getFileName()) .contentLength(resource.contentLength()) - .header("Content-Type", type.mediaType) + .header("Content-Type", type.getMediaType()) .cacheControl(CacheControl.noCache()) .eTag(tbResource.getHashCode()) .body(resource); diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 724e975792..67598b0e83 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -601,6 +601,13 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { return mockMvc.perform(getRequest); } + protected ResultActions doGet(String urlTemplate, HttpHeaders httpHeaders, Object... urlVariables) throws Exception { + MockHttpServletRequestBuilder getRequest = get(urlTemplate, urlVariables); + getRequest.headers(httpHeaders); + setJwtToken(getRequest); + return mockMvc.perform(getRequest); + } + protected T doGet(String urlTemplate, Class responseClass, Object... urlVariables) throws Exception { return readResponse(doGet(urlTemplate, urlVariables).andExpect(status().isOk()), responseClass); } diff --git a/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java index fa4beab094..111a08d571 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java @@ -16,11 +16,18 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.mockito.Mockito; +import org.springframework.http.HttpHeaders; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.web.servlet.ResultActions; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TbResource; @@ -35,6 +42,7 @@ import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; +import java.util.Base64; import java.util.Collections; import java.util.List; @@ -48,6 +56,9 @@ public class TbResourceControllerTest extends AbstractControllerTest { private static final String DEFAULT_FILE_NAME = "test.jks"; private static final String DEFAULT_FILE_NAME_2 = "test2.jks"; + private static final String JS_TEST_FILE_NAME = "test.js"; + private static final String TEST_DATA = "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLQpGSUxFIElORk9STUFUSU9OCgpPTUEgUGVybWFuZW50IERvY3VtZW50CiAgIEZpbGU6IE9NQS1TVVAtTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci1WMV8wXzEtMjAxOTAyMjEtQQogICBUeXBlOiB4bWwKClB1YmxpYyBSZWFjaGFibGUgSW5mb3JtYXRpb24KICAgUGF0aDogaHR0cDovL3d3dy5vcGVubW9iaWxlYWxsaWFuY2Uub3JnL3RlY2gvcHJvZmlsZXMKICAgTmFtZTogTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci12MV8wXzEueG1sCgpOT1JNQVRJVkUgSU5GT1JNQVRJT04KCiAgSW5mb3JtYXRpb24gYWJvdXQgdGhpcyBmaWxlIGNhbiBiZSBmb3VuZCBpbiB0aGUgbGF0ZXN0IHJldmlzaW9uIG9mCgogIE9NQS1UUy1MV00yTV9CaW5hcnlBcHBEYXRhQ29udGFpbmVyLVYxXzBfMQoKICBUaGlzIGlzIGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm9wZW5tb2JpbGVhbGxpYW5jZS5vcmcvCgogIFNlbmQgY29tbWVudHMgdG8gaHR0cHM6Ly9naXRodWIuY29tL09wZW5Nb2JpbGVBbGxpYW5jZS9PTUFfTHdNMk1fZm9yX0RldmVsb3BlcnMvaXNzdWVzCgpDSEFOR0UgSElTVE9SWQoKMTUwNjIwMTggU3RhdHVzIGNoYW5nZWQgdG8gQXBwcm92ZWQgYnkgRE0sIERvYyBSZWYgIyBPTUEtRE0mU0UtMjAxOC0wMDYxLUlOUF9MV00yTV9BUFBEQVRBX1YxXzBfRVJQX2Zvcl9maW5hbF9BcHByb3ZhbAoyMTAyMjAxOSBTdGF0dXMgY2hhbmdlZCB0byBBcHByb3ZlZCBieSBJUFNPLCBEb2MgUmVmICMgT01BLUlQU08tMjAxOS0wMDI1LUlOUF9Md00yTV9PYmplY3RfQXBwX0RhdGFfQ29udGFpbmVyXzFfMF8xX2Zvcl9GaW5hbF9BcHByb3ZhbAoKTEVHQUwgRElTQ0xBSU1FUgoKQ29weXJpZ2h0IDIwMTkgT3BlbiBNb2JpbGUgQWxsaWFuY2UuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCmFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodApub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCjIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Cm5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cwpjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwoiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVApMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUwpGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULApJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCkxJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOCkFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQpQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KClRoZSBhYm92ZSBsaWNlbnNlIGlzIHVzZWQgYXMgYSBsaWNlbnNlIHVuZGVyIGNvcHlyaWdodCBvbmx5LiBQbGVhc2UKcmVmZXJlbmNlIHRoZSBPTUEgSVBSIFBvbGljeSBmb3IgcGF0ZW50IGxpY2Vuc2luZyB0ZXJtczoKaHR0cHM6Ly93d3cub21hc3BlY3dvcmtzLm9yZy9hYm91dC9pbnRlbGxlY3R1YWwtcHJvcGVydHktcmlnaHRzLwoKLS0+CjxMV00yTSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj0iaHR0cDovL29wZW5tb2JpbGVhbGxpYW5jZS5vcmcvdGVjaC9wcm9maWxlcy9MV00yTS54c2QiPgoJPE9iamVjdCBPYmplY3RUeXBlPSJNT0RlZmluaXRpb24iPgoJCTxOYW1lPkJpbmFyeUFwcERhdGFDb250YWluZXI8L05hbWU+CgkJPERlc2NyaXB0aW9uMT48IVtDREFUQVtUaGlzIEx3TTJNIE9iamVjdHMgcHJvdmlkZXMgdGhlIGFwcGxpY2F0aW9uIHNlcnZpY2UgZGF0YSByZWxhdGVkIHRvIGEgTHdNMk0gU2VydmVyLCBlZy4gV2F0ZXIgbWV0ZXIgZGF0YS4gClRoZXJlIGFyZSBzZXZlcmFsIG1ldGhvZHMgdG8gY3JlYXRlIGluc3RhbmNlIHRvIGluZGljYXRlIHRoZSBtZXNzYWdlIGRpcmVjdGlvbiBiYXNlZCBvbiB0aGUgbmVnb3RpYXRpb24gYmV0d2VlbiBBcHBsaWNhdGlvbiBhbmQgTHdNMk0uIFRoZSBDbGllbnQgYW5kIFNlcnZlciBzaG91bGQgbmVnb3RpYXRlIHRoZSBpbnN0YW5jZShzKSB1c2VkIHRvIGV4Y2hhbmdlIHRoZSBkYXRhLiBGb3IgZXhhbXBsZToKIC0gVXNpbmcgYSBzaW5nbGUgaW5zdGFuY2UgZm9yIGJvdGggZGlyZWN0aW9ucyBjb21tdW5pY2F0aW9uLCBmcm9tIENsaWVudCB0byBTZXJ2ZXIgYW5kIGZyb20gU2VydmVyIHRvIENsaWVudC4KIC0gVXNpbmcgYW4gaW5zdGFuY2UgZm9yIGNvbW11bmljYXRpb24gZnJvbSBDbGllbnQgdG8gU2VydmVyIGFuZCBhbm90aGVyIG9uZSBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIFNlcnZlciB0byBDbGllbnQKIC0gVXNpbmcgc2V2ZXJhbCBpbnN0YW5jZXMKXV0+PC9EZXNjcmlwdGlvbjE+CgkJPE9iamVjdElEPjE5PC9PYmplY3RJRD4KCQk8T2JqZWN0VVJOPnVybjpvbWE6bHdtMm06b21hOjE5PC9PYmplY3RVUk4+CgkJPExXTTJNVmVyc2lvbj4xLjA8L0xXTTJNVmVyc2lvbj4KCQk8T2JqZWN0VmVyc2lvbj4xLjA8L09iamVjdFZlcnNpb24+CgkJPE11bHRpcGxlSW5zdGFuY2VzPk11bHRpcGxlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJPFJlc291cmNlcz4KCQkJPEl0ZW0gSUQ9IjAiPjxOYW1lPkRhdGE8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5NdWx0aXBsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk1hbmRhdG9yeTwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+T3BhcXVlPC9UeXBlPgoJCQkJPFJhbmdlRW51bWVyYXRpb24gLz4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBjb250ZW50Ll1dPjwvRGVzY3JpcHRpb24+CgkJCTwvSXRlbT4KCQkJPEl0ZW0gSUQ9IjEiPjxOYW1lPkRhdGEgUHJpb3JpdHk8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5TaW5nbGU8L011bHRpcGxlSW5zdGFuY2VzPgoJCQkJPE1hbmRhdG9yeT5PcHRpb25hbDwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+SW50ZWdlcjwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjEgYnl0ZXM8L1JhbmdlRW51bWVyYXRpb24+CgkJCQk8VW5pdHMgLz4KCQkJCTxEZXNjcmlwdGlvbj48IVtDREFUQVtJbmRpY2F0ZXMgdGhlIEFwcGxpY2F0aW9uIGRhdGEgcHJpb3JpdHk6CjA6SW1tZWRpYXRlCjE6QmVzdEVmZm9ydAoyOkxhdGVzdAozLTEwMDogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCjEwMS0yNTQ6IFByb3ByaWV0YXJ5IG1vZGUuXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iMiI+PE5hbWU+RGF0YSBDcmVhdGlvbiBUaW1lPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlRpbWU8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbiAvPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBEYXRhIGluc3RhbmNlIGNyZWF0aW9uIHRpbWVzdGFtcC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSIzIj48TmFtZT5EYXRhIERlc2NyaXB0aW9uPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlN0cmluZzwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjMyIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkYXRhIGRlc2NyaXB0aW9uLgplLmcuICJtZXRlciByZWFkaW5nIi5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSI0Ij48TmFtZT5EYXRhIEZvcm1hdDwvTmFtZT4KCQkJCTxPcGVyYXRpb25zPlJXPC9PcGVyYXRpb25zPgoJCQkJPE11bHRpcGxlSW5zdGFuY2VzPlNpbmdsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJCQk8VHlwZT5TdHJpbmc8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4zMiBieXRlczwvUmFuZ2VFbnVtZXJhdGlvbj4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgZm9ybWF0IG9mIHRoZSBBcHBsaWNhdGlvbiBEYXRhLgplLmcuIFlHLU1ldGVyLVdhdGVyLVJlYWRpbmcKVVRGOC1zdHJpbmcKXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iNSI+PE5hbWU+QXBwIElEPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPkludGVnZXI8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4yIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkZXN0aW5hdGlvbiBBcHBsaWNhdGlvbiBJRC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+PC9SZXNvdXJjZXM+CgkJPERlc2NyaXB0aW9uMj48IVtDREFUQVtdXT48L0Rlc2NyaXB0aW9uMj4KCTwvT2JqZWN0Pgo8L0xXTTJNPgo="; + private Tenant savedTenant; private User tenantAdmin; @@ -88,7 +99,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My first resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = save(resource); @@ -123,7 +134,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle(StringUtils.randomAlphabetic(300)); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); Mockito.reset(tbClusterService, auditLogService); @@ -142,7 +153,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My first resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = save(resource); @@ -171,7 +182,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My first resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = save(resource); @@ -186,7 +197,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My first resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = save(resource); @@ -217,7 +228,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setTitle("Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); resources.add(new TbResourceInfo(save(resource))); } List loadedResources = new ArrayList<>(); @@ -254,7 +265,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setTitle("JKS Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); resources.add(new TbResourceInfo(save(resource))); } @@ -264,7 +275,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setTitle("LWM2M Resource" + i); resource.setResourceType(ResourceType.PKCS_12); resource.setFileName(i + DEFAULT_FILE_NAME_2); - resource.setData("Test Data"); + resource.setData(TEST_DATA); save(resource); } @@ -301,7 +312,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setTitle("Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); resources.add(new TbResourceInfo(save(resource))); } List loadedResources = new ArrayList<>(); @@ -361,7 +372,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setTitle("JKS Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResourceInfo saved = new TbResourceInfo(save(resource)); jksResources.add(saved); } @@ -372,7 +383,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setTitle("LWM2M Resource" + i); resource.setResourceType(ResourceType.PKCS_12); resource.setFileName(i + DEFAULT_FILE_NAME_2); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource saved = save(resource); lwm2mesources.add(saved); } @@ -438,7 +449,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setTitle("Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); expectedResources.add(new TbResourceInfo(save(resource))); } @@ -449,7 +460,7 @@ public class TbResourceControllerTest extends AbstractControllerTest { resource.setTitle("Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResourceInfo savedResource = new TbResourceInfo(save(resource)); systemResources.add(savedResource); if (i >= 73) { @@ -485,6 +496,81 @@ public class TbResourceControllerTest extends AbstractControllerTest { } } + @Test + public void testDownloadTbResourceIfChanged() throws Exception { + Mockito.reset(tbClusterService, auditLogService); + + TbResource resource = new TbResource(); + resource.setResourceType(ResourceType.JS_MODULE); + resource.setTitle("Js resource"); + resource.setFileName(JS_TEST_FILE_NAME); + resource.setData(TEST_DATA); + + TbResource savedResource = save(resource); + + testNotifyEntityOneTimeMsgToEdgeServiceNever(savedResource, savedResource.getId(), savedResource.getId(), + savedTenant.getId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ADDED); + + ResultActions resultActions = doGet("/api/resource/js/" + savedResource.getId().getId().toString() + "/download") + .andExpect(status().isOk()); + MockHttpServletResponse response = resultActions.andReturn().getResponse(); + String eTag = response.getHeader("ETag"); + Assert.assertNotNull(eTag); + Assert.assertEquals(Base64.getEncoder().encodeToString(response.getContentAsByteArray()), TEST_DATA); + + //download with if-none-match header + HttpHeaders headers = new HttpHeaders(); + headers.setIfNoneMatch(eTag); + doGet("/api/resource/js/" + savedResource.getId().getId().toString() + "/download", headers) + .andExpect(status().isNotModified()); + } + + @Ignore + @Test + public void testDownloadTbResourceIfChangedAsPublicCustomer() throws Exception { + loginTenantAdmin(); + Mockito.reset(tbClusterService, auditLogService); + + TbResource resource = new TbResource(); + resource.setResourceType(ResourceType.JS_MODULE); + resource.setTitle("Js resource"); + resource.setFileName(JS_TEST_FILE_NAME); + resource.setData(TEST_DATA); + + TbResource savedResource = save(resource); + + //download as public customer + Device device = new Device(); + device.setName("Test Public Device"); + device.setLabel("Label"); + device.setCustomerId(customerId); + device = doPost("/api/device", device, Device.class); + device = doPost("/api/customer/public/device/" + device.getUuidId(), Device.class); + + String publicId = device.getCustomerId().toString(); + + Mockito.reset(tbClusterService, auditLogService); + resetTokens(); + + JsonNode publicLoginRequest = JacksonUtil.toJsonNode("{\"publicId\": \"" + publicId + "\"}"); + JsonNode tokens = doPost("/api/auth/login/public", publicLoginRequest, JsonNode.class); + this.token = tokens.get("token").asText(); + + ResultActions resultActions = doGet("/api/resource/js/" + savedResource.getId().getId().toString() + "/download") + .andExpect(status().isOk()); + MockHttpServletResponse response = resultActions.andReturn().getResponse(); + String eTag = response.getHeader("ETag"); + Assert.assertNotNull(eTag); + Assert.assertEquals(Base64.getEncoder().encodeToString(response.getContentAsByteArray()), TEST_DATA); + + //download with if-none-match header + HttpHeaders headers = new HttpHeaders(); + headers.setIfNoneMatch(eTag); + doGet("/api/resource/js/" + savedResource.getId().getId().toString() + "/download", headers) + .andExpect(status().isNotModified()); + } + private TbResource save(TbResource tbResource) throws Exception { return doPostWithTypedResponse("/api/resource", tbResource, new TypeReference<>(){}); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java index bef4681c05..b67cd49aff 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java @@ -21,11 +21,28 @@ public enum ResourceType { PKCS_12("pkcs12", "application/x-pkcs12"), JS_MODULE("js", "application/javascript"); - public String type; - public String mediaType; + private final String type; + private final String mediaType; ResourceType(String type, String mediaType) { this.type = type; this.mediaType = mediaType; } + + public static ResourceType getResourceByType(String type) { + for(ResourceType resourceType : values()) { + if (resourceType.getType().equalsIgnoreCase(type)) { + return resourceType; + } + } + throw new IllegalArgumentException(); + } + + public String getMediaType() { + return mediaType; + } + + public String getType() { + return type; + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java index 54dca66657..cb2dcf3133 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java @@ -29,6 +29,7 @@ import javax.persistence.Entity; import javax.persistence.Table; import java.util.UUID; +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_HASH_CODE_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_KEY_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TENANT_ID_COLUMN; @@ -57,6 +58,9 @@ public class TbResourceInfoEntity extends BaseSqlEntity implemen @Column(name = SEARCH_TEXT_PROPERTY) private String searchText; + @Column(name = RESOURCE_HASH_CODE_COLUMN) + private String hashCode; + public TbResourceInfoEntity() { } @@ -70,6 +74,7 @@ public class TbResourceInfoEntity extends BaseSqlEntity implemen this.resourceType = resource.getResourceType().name(); this.resourceKey = resource.getResourceKey(); this.searchText = resource.getSearchText(); + this.hashCode = resource.getHashCode(); } @Override @@ -81,6 +86,7 @@ public class TbResourceInfoEntity extends BaseSqlEntity implemen resource.setResourceType(ResourceType.valueOf(resourceType)); resource.setResourceKey(resourceKey); resource.setSearchText(searchText); + resource.setHashCode(hashCode); return resource; } } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 6f0969056c..62231e6995 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -697,6 +697,7 @@ CREATE TABLE IF NOT EXISTS resource ( search_text varchar(255), file_name varchar(255) NOT NULL, data varchar, + hash_code varchar, CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key) ); From 06dd2044659e214bdf0fc209330922aacbc37d15 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 7 Jun 2023 13:38:47 +0300 Subject: [PATCH 137/207] refactoring --- .../server/controller/TbResourceController.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index 369dc2e2bd..fad26f72f7 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -105,7 +105,7 @@ public class TbResourceController extends BaseController { .body(resource); } - @ApiOperation(value = "Download Resource (downloadResource)", notes = "Download Resource based on the provided Resource Id." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Download LWM2M Resource (downloadLwm2mResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/lwm2m/{resourceId}/download", method = RequestMethod.GET) @ResponseBody @@ -114,7 +114,7 @@ public class TbResourceController extends BaseController { return downloadResourceIfChanged(ResourceType.LWM2M_MODEL, strResourceId, headers); } - @ApiOperation(value = "Download Resource (downloadResource)", notes = "Download Resource based on the provided Resource Id." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Download PKCS_12 Resource (downloadPkcs12ResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/pkcs12/{resourceId}/download", method = RequestMethod.GET) @ResponseBody @@ -123,7 +123,16 @@ public class TbResourceController extends BaseController { return downloadResourceIfChanged(ResourceType.PKCS_12, strResourceId, headers); } - @ApiOperation(value = "Download Resource (downloadResource)", notes = "Download Resource based on the provided Resource Id." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Download JKS Resource (downloadJksResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(value = "/resource/jks/{resourceId}/download", method = RequestMethod.GET) + @ResponseBody + public ResponseEntity downloadJksResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader HttpHeaders headers) throws ThingsboardException { + return downloadResourceIfChanged(ResourceType.JKS, strResourceId, headers); + } + + @ApiOperation(value = "Download JS Resource (downloadJsResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/js/{resourceId}/download", method = RequestMethod.GET) @ResponseBody From 407effbc2629bc67006300e655c1118da5e61ea7 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 7 Jun 2023 14:08:55 +0300 Subject: [PATCH 138/207] refactoring --- .../controller/TbResourceController.java | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index fad26f72f7..6e8977a886 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -110,8 +110,8 @@ public class TbResourceController extends BaseController { @RequestMapping(value = "/resource/lwm2m/{resourceId}/download", method = RequestMethod.GET) @ResponseBody public ResponseEntity downloadLwm2mResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader HttpHeaders headers) throws ThingsboardException { - return downloadResourceIfChanged(ResourceType.LWM2M_MODEL, strResourceId, headers); + @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { + return downloadResourceIfChanged(ResourceType.LWM2M_MODEL, strResourceId, etag); } @ApiOperation(value = "Download PKCS_12 Resource (downloadPkcs12ResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @@ -119,8 +119,8 @@ public class TbResourceController extends BaseController { @RequestMapping(value = "/resource/pkcs12/{resourceId}/download", method = RequestMethod.GET) @ResponseBody public ResponseEntity downloadPkcs12ResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader HttpHeaders headers) throws ThingsboardException { - return downloadResourceIfChanged(ResourceType.PKCS_12, strResourceId, headers); + @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { + return downloadResourceIfChanged(ResourceType.PKCS_12, strResourceId, etag); } @ApiOperation(value = "Download JKS Resource (downloadJksResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @@ -128,17 +128,17 @@ public class TbResourceController extends BaseController { @RequestMapping(value = "/resource/jks/{resourceId}/download", method = RequestMethod.GET) @ResponseBody public ResponseEntity downloadJksResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader HttpHeaders headers) throws ThingsboardException { - return downloadResourceIfChanged(ResourceType.JKS, strResourceId, headers); + @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { + return downloadResourceIfChanged(ResourceType.JKS, strResourceId, etag); } @ApiOperation(value = "Download JS Resource (downloadJsResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) - @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/resource/js/{resourceId}/download", method = RequestMethod.GET) @ResponseBody public ResponseEntity downloadJsResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader HttpHeaders headers) throws ThingsboardException { - return downloadResourceIfChanged(ResourceType.JS_MODULE, strResourceId, headers); + @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { + return downloadResourceIfChanged(ResourceType.JS_MODULE, strResourceId, etag); } @ApiOperation(value = "Get Resource Info (getResourceInfoById)", @@ -271,21 +271,20 @@ public class TbResourceController extends BaseController { tbResourceService.delete(tbResource, getCurrentUser()); } - private ResponseEntity downloadResourceIfChanged(ResourceType type, String strResourceId, HttpHeaders headers) throws ThingsboardException { + private ResponseEntity downloadResourceIfChanged(ResourceType type, String strResourceId, String etag) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); - TbResourceInfo tbResourceInfo = checkResourceInfoId(resourceId, Operation.READ); - List ifNoneMatchHeaders = headers.getIfNoneMatch(); - if (!ifNoneMatchHeaders.isEmpty()) { - if (ifNoneMatchHeaders.contains(tbResourceInfo.getHashCode())) { + if (etag != null) { + TbResourceInfo tbResourceInfo = checkResourceInfoId(resourceId, Operation.READ); + if (etag.equals(tbResourceInfo.getHashCode())) { return ResponseEntity.status(HttpStatus.NOT_MODIFIED) - .eTag(tbResourceInfo.getHashCode()).build(); + .eTag(tbResourceInfo.getHashCode()) + .build(); } } - SecurityUser currentUser = getCurrentUser(); - TbResource tbResource = resourceService.findResourceById(currentUser.getTenantId(), resourceId); + TbResource tbResource = checkResourceId(resourceId, Operation.READ); ByteArrayResource resource = new ByteArrayResource(Base64.getDecoder().decode(tbResource.getData().getBytes())); return ResponseEntity.ok() From 138128d83751f21e1a76bd8032e2eb868b0cfc2e Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 7 Jun 2023 15:18:45 +0300 Subject: [PATCH 139/207] added more logs to RPC processing logic in MQTT and CoAP transports --- .../transport/coap/CoapTestCallback.java | 12 ----- ...AbstractCoapAttributesIntegrationTest.java | 4 +- ...tractCoapServerSideRpcIntegrationTest.java | 49 ++++++++----------- .../mqtt/mqttv3/MqttTestCallback.java | 28 ++--------- .../MqttTestSubscribeOnTopicCallback.java | 45 +++++++++++++++++ ...AbstractMqttAttributesIntegrationTest.java | 13 ++--- .../MqttProvisionJsonDeviceTest.java | 3 +- .../MqttProvisionProtoDeviceTest.java | 3 +- ...tractMqttServerSideRpcIntegrationTest.java | 17 ++++--- .../src/test/resources/logback-test.xml | 6 +++ .../coap/client/DefaultCoapClientContext.java | 12 +++-- .../transport/mqtt/MqttTransportHandler.java | 10 ++-- 12 files changed, 115 insertions(+), 87 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestSubscribeOnTopicCallback.java diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/CoapTestCallback.java b/application/src/test/java/org/thingsboard/server/transport/coap/CoapTestCallback.java index 2dda86d7a4..07eadd731d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/coap/CoapTestCallback.java +++ b/application/src/test/java/org/thingsboard/server/transport/coap/CoapTestCallback.java @@ -21,25 +21,14 @@ import org.eclipse.californium.core.CoapHandler; import org.eclipse.californium.core.CoapResponse; import org.eclipse.californium.core.coap.CoAP; -import java.util.concurrent.CountDownLatch; - @Slf4j @Data public class CoapTestCallback implements CoapHandler { - protected final CountDownLatch latch; protected Integer observe; protected byte[] payloadBytes; protected CoAP.ResponseCode responseCode; - public CoapTestCallback() { - this.latch = new CountDownLatch(1); - } - - public CoapTestCallback(int subscribeCount) { - this.latch = new CountDownLatch(subscribeCount); - } - public Integer getObserve() { return observe; } @@ -57,7 +46,6 @@ public class CoapTestCallback implements CoapHandler { observe = response.getOptions().getObserve(); payloadBytes = response.getPayload(); responseCode = response.getCode(); - latch.countDown(); } @Override diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/attributes/AbstractCoapAttributesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/attributes/AbstractCoapAttributesIntegrationTest.java index 697779c178..03ef6f9503 100644 --- a/application/src/test/java/org/thingsboard/server/transport/coap/attributes/AbstractCoapAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/coap/attributes/AbstractCoapAttributesIntegrationTest.java @@ -232,7 +232,7 @@ public abstract class AbstractCoapAttributesIntegrationTest extends AbstractCoap } client = new CoapTestClient(accessToken, FeatureType.ATTRIBUTES); - CoapTestCallback callbackCoap = new CoapTestCallback(1); + CoapTestCallback callbackCoap = new CoapTestCallback(); CoapObserveRelation observeRelation = client.getObserveRelation(callbackCoap); String awaitAlias = "await Json Test Subscribe To AttributesUpdates (client.getObserveRelation)"; @@ -279,7 +279,7 @@ public abstract class AbstractCoapAttributesIntegrationTest extends AbstractCoap } client = new CoapTestClient(accessToken, FeatureType.ATTRIBUTES); - CoapTestCallback callbackCoap = new CoapTestCallback(1); + CoapTestCallback callbackCoap = new CoapTestCallback(); String awaitAlias = "await Proto Test Subscribe To Attributes Updates (add attributes)"; CoapObserveRelation observeRelation = client.getObserveRelation(callbackCoap); diff --git a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java index a2b44b6e58..445ac51ccd 100644 --- a/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/coap/rpc/AbstractCoapServerSideRpcIntegrationTest.java @@ -41,7 +41,6 @@ import org.thingsboard.server.transport.coap.AbstractCoapIntegrationTest; import org.thingsboard.server.transport.coap.CoapTestCallback; import org.thingsboard.server.transport.coap.CoapTestClient; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.awaitility.Awaitility.await; @@ -74,17 +73,16 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC protected void processOneWayRpcTest(boolean protobuf) throws Exception { client = new CoapTestClient(accessToken, FeatureType.RPC); - CoapTestCallback callbackCoap = new TestCoapCallbackForRPC(client, 1, true, protobuf); + CoapTestCallback callbackCoap = new TestCoapCallbackForRPC(client, true, protobuf); CoapObserveRelation observeRelation = client.getObserveRelation(callbackCoap); String awaitAlias = "await One Way Rpc (client.getObserveRelation)"; await(awaitAlias) .atMost(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS) .until(() -> CoAP.ResponseCode.VALID.equals(callbackCoap.getResponseCode()) && - callbackCoap.getObserve() != null && - 0 == callbackCoap.getObserve().intValue()); + callbackCoap.getObserve() != null && 0 == callbackCoap.getObserve()); validateCurrentStateNotification(callbackCoap); - int expectedObserveCountAfterGpioRequest = callbackCoap.getObserve().intValue() + 1; + int expectedObserveAfterRpcProcessed = callbackCoap.getObserve() + 1; String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"23\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); String result = doPostAsync("/api/rpc/oneway/" + deviceId, setGpioRequest, String.class, status().isOk()); @@ -92,8 +90,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC await(awaitAlias) .atMost(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS) .until(() -> CoAP.ResponseCode.CONTENT.equals(callbackCoap.getResponseCode()) && - callbackCoap.getObserve() != null && - expectedObserveCountAfterGpioRequest == callbackCoap.getObserve().intValue()); + callbackCoap.getObserve() != null && expectedObserveAfterRpcProcessed == callbackCoap.getObserve()); validateOneWayStateChangedNotification(callbackCoap, result); observeRelation.proactiveCancel(); @@ -102,7 +99,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC protected void processTwoWayRpcTest(String expectedResponseResult, boolean protobuf) throws Exception { client = new CoapTestClient(accessToken, FeatureType.RPC); - CoapTestCallback callbackCoap = new TestCoapCallbackForRPC(client, 1, false, protobuf); + CoapTestCallback callbackCoap = new TestCoapCallbackForRPC(client, false, protobuf); CoapObserveRelation observeRelation = client.getObserveRelation(callbackCoap); String awaitAlias = "await Two Way Rpc (client.getObserveRelation)"; @@ -110,29 +107,29 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC .atMost(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS) .until(() -> CoAP.ResponseCode.VALID.equals(callbackCoap.getResponseCode()) && callbackCoap.getObserve() != null && - 0 == callbackCoap.getObserve().intValue()); + 0 == callbackCoap.getObserve()); validateCurrentStateNotification(callbackCoap); String setGpioRequest = "{\"method\":\"setGpio\",\"params\":{\"pin\": \"26\",\"value\": 1}}"; String deviceId = savedDevice.getId().getId().toString(); - int expectedObserveCountAfterGpioRequest1 = callbackCoap.getObserve().intValue() + 1; + int expectedObserveCountAfterGpioRequest1 = callbackCoap.getObserve() + 1; String actualResult = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); awaitAlias = "await Two Way Rpc (setGpio(method, params, value) first"; await(awaitAlias) .atMost(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS) .until(() -> CoAP.ResponseCode.CONTENT.equals(callbackCoap.getResponseCode()) && callbackCoap.getObserve() != null && - expectedObserveCountAfterGpioRequest1 == callbackCoap.getObserve().intValue()); + expectedObserveCountAfterGpioRequest1 == callbackCoap.getObserve()); validateTwoWayStateChangedNotification(callbackCoap, expectedResponseResult, actualResult); - int expectedObserveCountAfterGpioRequest2 = callbackCoap.getObserve().intValue() + 1; + int expectedObserveCountAfterGpioRequest2 = callbackCoap.getObserve() + 1; actualResult = doPostAsync("/api/rpc/twoway/" + deviceId, setGpioRequest, String.class, status().isOk()); awaitAlias = "await Two Way Rpc (setGpio(method, params, value) first"; await(awaitAlias) .atMost(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS) .until(() -> CoAP.ResponseCode.CONTENT.equals(callbackCoap.getResponseCode()) && callbackCoap.getObserve() != null && - expectedObserveCountAfterGpioRequest2 == callbackCoap.getObserve().intValue()); + expectedObserveCountAfterGpioRequest2 == callbackCoap.getObserve()); validateTwoWayStateChangedNotification(callbackCoap, expectedResponseResult, actualResult); @@ -140,24 +137,24 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC assertTrue(observeRelation.isCanceled()); } - protected void processOnLoadResponse(CoapResponse response, CoapTestClient client, Integer observe, CountDownLatch latch) { + protected void processOnLoadResponse(CoapResponse response, CoapTestClient client) { JsonNode responseJson = JacksonUtil.fromBytes(response.getPayload()); - client.setURI(CoapTestClient.getFeatureTokenUrl(accessToken, FeatureType.RPC, responseJson.get("id").asInt())); + int requestId = responseJson.get("id").asInt(); + client.setURI(CoapTestClient.getFeatureTokenUrl(accessToken, FeatureType.RPC, requestId)); client.postMethod(new CoapHandler() { @Override public void onLoad(CoapResponse response) { - log.warn("Command Response Ack: {}, {}", response.getCode(), response.getResponseText()); - latch.countDown(); + log.warn("RPC {} command response ack: {}", requestId, response.getCode()); } @Override public void onError() { - log.warn("Command Response Ack Error, No connect"); + log.warn("RPC {} command response ack error, no connect", requestId); } }, DEVICE_RESPONSE, MediaTypeRegistry.APPLICATION_JSON); } - protected void processOnLoadProtoResponse(CoapResponse response, CoapTestClient client, Integer observe, CountDownLatch latch) { + protected void processOnLoadProtoResponse(CoapResponse response, CoapTestClient client) { ProtoTransportPayloadConfiguration protoTransportPayloadConfiguration = getProtoTransportPayloadConfiguration(); ProtoFileElement rpcRequestProtoFileElement = DynamicProtoUtils.getProtoFileElement(protoTransportPayloadConfiguration.getDeviceRpcRequestProtoSchema()); DynamicSchema rpcRequestProtoSchema = DynamicProtoUtils.getDynamicSchema(rpcRequestProtoFileElement, ProtoTransportPayloadConfiguration.RPC_REQUEST_PROTO_SCHEMA); @@ -180,13 +177,12 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC client.postMethod(new CoapHandler() { @Override public void onLoad(CoapResponse response) { - log.warn("Command Response Ack: {}", response.getCode()); - latch.countDown(); + log.warn("RPC {} command response ack: {}", requestId, response.getCode()); } @Override public void onError() { - log.warn("Command Response Ack Error, No connect"); + log.warn("RPC {} command response ack error, no connect", requestId); } }, rpcResponseMsg.toByteArray(), MediaTypeRegistry.APPLICATION_JSON); } catch (InvalidProtocolBufferException e) { @@ -226,8 +222,7 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC private final boolean isOneWayRpc; private final boolean protobuf; - TestCoapCallbackForRPC(CoapTestClient client, int subscribeCount, boolean isOneWayRpc, boolean protobuf) { - super(subscribeCount); + TestCoapCallbackForRPC(CoapTestClient client, boolean isOneWayRpc, boolean protobuf) { this.client = client; this.isOneWayRpc = isOneWayRpc; this.protobuf = protobuf; @@ -241,12 +236,10 @@ public abstract class AbstractCoapServerSideRpcIntegrationTest extends AbstractC if (observe != null) { if (!isOneWayRpc && observe > 0) { if (!protobuf){ - processOnLoadResponse(response, client, observe, latch); + processOnLoadResponse(response, client); } else { - processOnLoadProtoResponse(response, client, observe, latch); + processOnLoadProtoResponse(response, client); } - } else { - latch.countDown(); } } } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestCallback.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestCallback.java index 3240647956..208189ac4e 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestCallback.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestCallback.java @@ -32,7 +32,6 @@ public class MqttTestCallback implements MqttCallback { protected final CountDownLatch deliveryLatch; protected int qoS; protected byte[] payloadBytes; - protected String awaitSubTopic; protected boolean pubAckReceived; public MqttTestCallback() { @@ -45,12 +44,6 @@ public class MqttTestCallback implements MqttCallback { this.deliveryLatch = new CountDownLatch(1); } - public MqttTestCallback(String awaitSubTopic) { - this.subscribeLatch = new CountDownLatch(1); - this.deliveryLatch = new CountDownLatch(1); - this.awaitSubTopic = awaitSubTopic; - } - @Override public void connectionLost(Throwable throwable) { log.warn("connectionLost: ", throwable); @@ -59,23 +52,10 @@ public class MqttTestCallback implements MqttCallback { @Override public void messageArrived(String requestTopic, MqttMessage mqttMessage) { - if (awaitSubTopic == null) { - log.warn("messageArrived on topic: {}", requestTopic); - qoS = mqttMessage.getQos(); - payloadBytes = mqttMessage.getPayload(); - subscribeLatch.countDown(); - } else { - messageArrivedOnAwaitSubTopic(requestTopic, mqttMessage); - } - } - - protected void messageArrivedOnAwaitSubTopic(String requestTopic, MqttMessage mqttMessage) { - log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); - if (awaitSubTopic.equals(requestTopic)) { - qoS = mqttMessage.getQos(); - payloadBytes = mqttMessage.getPayload(); - subscribeLatch.countDown(); - } + log.warn("messageArrived on topic: {}", requestTopic); + qoS = mqttMessage.getQos(); + payloadBytes = mqttMessage.getPayload(); + subscribeLatch.countDown(); } @Override diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestSubscribeOnTopicCallback.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestSubscribeOnTopicCallback.java new file mode 100644 index 0000000000..0f3cc14629 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/MqttTestSubscribeOnTopicCallback.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.mqtt.mqttv3; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttMessage; + +@Data +@Slf4j +@EqualsAndHashCode(callSuper = true) +public class MqttTestSubscribeOnTopicCallback extends MqttTestCallback { + + protected final String awaitSubTopic; + + public MqttTestSubscribeOnTopicCallback(String awaitSubTopic) { + super(); + this.awaitSubTopic = awaitSubTopic; + } + + @Override + public void messageArrived(String requestTopic, MqttMessage mqttMessage) { + log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); + if (awaitSubTopic.equals(requestTopic)) { + qoS = mqttMessage.getQos(); + payloadBytes = mqttMessage.getPayload(); + subscribeLatch.countDown(); + } + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/AbstractMqttAttributesIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/AbstractMqttAttributesIntegrationTest.java index 941e97e500..71d8809e38 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/AbstractMqttAttributesIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/attributes/AbstractMqttAttributesIntegrationTest.java @@ -45,6 +45,7 @@ import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityDataUpdate; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestSubscribeOnTopicCallback; import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import java.util.ArrayList; @@ -358,7 +359,7 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt String update = getWsClient().waitForUpdate(); assertThat(update).as("ws update received").isNotBlank(); - MqttTestCallback callback = new MqttTestCallback(attrSubTopic.replace("+", "1")); + MqttTestCallback callback = new MqttTestSubscribeOnTopicCallback(attrSubTopic.replace("+", "1")); client.setCallback(callback); String payloadStr = "{\"clientKeys\":\"" + clientKeysStr + "\", \"sharedKeys\":\"" + sharedKeysStr + "\"}"; client.publishAndWait(attrReqTopicPrefix + "1", payloadStr.getBytes()); @@ -389,7 +390,7 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt String update = getWsClient().waitForUpdate(); assertThat(update).as("ws update received").isNotBlank(); - MqttTestCallback callback = new MqttTestCallback(attrSubTopic.replace("+", "1")); + MqttTestCallback callback = new MqttTestSubscribeOnTopicCallback(attrSubTopic.replace("+", "1")); client.setCallback(callback); TransportApiProtos.AttributesRequest.Builder attributesRequestBuilder = TransportApiProtos.AttributesRequest.newBuilder(); attributesRequestBuilder.setClientKeys(clientKeysStr); @@ -448,14 +449,14 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt client.subscribeAndWait(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE); //RequestAttributes does not make any subscriptions in device actor - MqttTestCallback clientAttributesCallback = new MqttTestCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); + MqttTestCallback clientAttributesCallback = new MqttTestSubscribeOnTopicCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); client.setCallback(clientAttributesCallback); String csKeysStr = "[\"clientStr\", \"clientBool\", \"clientDbl\", \"clientLong\", \"clientJson\"]"; String csRequestPayloadStr = "{\"id\": 1, \"device\": \"" + deviceName + "\", \"client\": true, \"keys\": " + csKeysStr + "}"; client.publishAndWait(GATEWAY_ATTRIBUTES_REQUEST_TOPIC, csRequestPayloadStr.getBytes()); validateJsonResponseGateway(clientAttributesCallback, deviceName, CLIENT_ATTRIBUTES_PAYLOAD); - MqttTestCallback sharedAttributesCallback = new MqttTestCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); + MqttTestCallback sharedAttributesCallback = new MqttTestSubscribeOnTopicCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); client.setCallback(sharedAttributesCallback); String shKeysStr = "[\"sharedStr\", \"sharedBool\", \"sharedDbl\", \"sharedLong\", \"sharedJson\"]"; String shRequestPayloadStr = "{\"id\": 1, \"device\": \"" + deviceName + "\", \"client\": false, \"keys\": " + shKeysStr + "}"; @@ -502,13 +503,13 @@ public abstract class AbstractMqttAttributesIntegrationTest extends AbstractMqtt client.subscribeAndWait(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC, MqttQoS.AT_LEAST_ONCE); awaitForDeviceActorToReceiveSubscription(device.getId(), FeatureType.ATTRIBUTES, 1); - MqttTestCallback clientAttributesCallback = new MqttTestCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); + MqttTestCallback clientAttributesCallback = new MqttTestSubscribeOnTopicCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); client.setCallback(clientAttributesCallback); TransportApiProtos.GatewayAttributesRequestMsg gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(deviceName, clientKeysList, true); client.publishAndWait(GATEWAY_ATTRIBUTES_REQUEST_TOPIC, gatewayAttributesRequestMsg.toByteArray()); validateProtoClientResponseGateway(clientAttributesCallback, deviceName); - MqttTestCallback sharedAttributesCallback = new MqttTestCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); + MqttTestCallback sharedAttributesCallback = new MqttTestSubscribeOnTopicCallback(GATEWAY_ATTRIBUTES_RESPONSE_TOPIC); client.setCallback(sharedAttributesCallback); gatewayAttributesRequestMsg = getGatewayAttributesRequestMsg(deviceName, sharedKeysList, false); client.publishAndWait(GATEWAY_ATTRIBUTES_REQUEST_TOPIC, gatewayAttributesRequestMsg.toByteArray()); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionJsonDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionJsonDeviceTest.java index 9081baa420..de0a3d6f3c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionJsonDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionJsonDeviceTest.java @@ -35,6 +35,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestSubscribeOnTopicCallback; import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import java.util.concurrent.TimeUnit; @@ -270,7 +271,7 @@ public class MqttProvisionJsonDeviceTest extends AbstractMqttIntegrationTest { String provisionRequestMsg = createTestProvisionMessage(deviceCredentials); MqttTestClient client = new MqttTestClient(); client.connectAndWait("provision"); - MqttTestCallback onProvisionCallback = new MqttTestCallback(DEVICE_PROVISION_RESPONSE_TOPIC); + MqttTestCallback onProvisionCallback = new MqttTestSubscribeOnTopicCallback(DEVICE_PROVISION_RESPONSE_TOPIC); client.setCallback(onProvisionCallback); client.subscribe(DEVICE_PROVISION_RESPONSE_TOPIC, MqttQoS.AT_MOST_ONCE); client.publishAndWait(DEVICE_PROVISION_REQUEST_TOPIC, provisionRequestMsg.getBytes()); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionProtoDeviceTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionProtoDeviceTest.java index fcea0f249b..c6d013ba20 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionProtoDeviceTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/provision/MqttProvisionProtoDeviceTest.java @@ -43,6 +43,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509Ce import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; import org.thingsboard.server.transport.mqtt.MqttTestConfigProperties; import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestSubscribeOnTopicCallback; import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import java.util.concurrent.TimeUnit; @@ -269,7 +270,7 @@ public class MqttProvisionProtoDeviceTest extends AbstractMqttIntegrationTest { protected byte[] createMqttClientAndPublish(byte[] provisionRequestMsg) throws Exception { MqttTestClient client = new MqttTestClient(); client.connectAndWait("provision"); - MqttTestCallback onProvisionCallback = new MqttTestCallback(DEVICE_PROVISION_RESPONSE_TOPIC); + MqttTestCallback onProvisionCallback = new MqttTestSubscribeOnTopicCallback(DEVICE_PROVISION_RESPONSE_TOPIC); client.setCallback(onProvisionCallback); client.subscribe(DEVICE_PROVISION_RESPONSE_TOPIC, MqttQoS.AT_MOST_ONCE); client.publishAndWait(DEVICE_PROVISION_REQUEST_TOPIC, provisionRequestMsg); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/AbstractMqttServerSideRpcIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/AbstractMqttServerSideRpcIntegrationTest.java index 8537ee9fd8..e1f20a3d95 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/AbstractMqttServerSideRpcIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/mqttv3/rpc/AbstractMqttServerSideRpcIntegrationTest.java @@ -41,6 +41,7 @@ import org.thingsboard.server.common.msg.session.FeatureType; import org.thingsboard.server.gen.transport.TransportApiProtos; import org.thingsboard.server.transport.mqtt.AbstractMqttIntegrationTest; import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestCallback; +import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestSubscribeOnTopicCallback; import org.thingsboard.server.transport.mqtt.mqttv3.MqttTestClient; import java.util.ArrayList; @@ -81,7 +82,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM protected void processOneWayRpcTest(String rpcSubTopic) throws Exception { MqttTestClient client = new MqttTestClient(); client.connectAndWait(accessToken); - MqttTestCallback callback = new MqttTestCallback(rpcSubTopic.replace("+", "0")); + MqttTestCallback callback = new MqttTestSubscribeOnTopicCallback(rpcSubTopic.replace("+", "0")); client.setCallback(callback); subscribeAndWait(client, rpcSubTopic, savedDevice.getId(), FeatureType.RPC); @@ -221,7 +222,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM ); assertNotNull(savedDevice); - MqttTestCallback callback = new MqttTestCallback(GATEWAY_RPC_TOPIC); + MqttTestCallback callback = new MqttTestSubscribeOnTopicCallback(GATEWAY_RPC_TOPIC); client.setCallback(callback); subscribeAndCheckSubscription(client, GATEWAY_RPC_TOPIC, savedDevice.getId(), FeatureType.RPC); @@ -320,7 +321,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM } } - protected class MqttTestRpcJsonCallback extends MqttTestCallback { + protected class MqttTestRpcJsonCallback extends MqttTestSubscribeOnTopicCallback { private final MqttTestClient client; @@ -330,7 +331,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM } @Override - protected void messageArrivedOnAwaitSubTopic(String requestTopic, MqttMessage mqttMessage) { + public void messageArrived(String requestTopic, MqttMessage mqttMessage) { log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); if (awaitSubTopic.equals(requestTopic)) { qoS = mqttMessage.getQos(); @@ -349,9 +350,10 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM subscribeLatch.countDown(); } } + } - protected class MqttTestRpcProtoCallback extends MqttTestCallback { + protected class MqttTestRpcProtoCallback extends MqttTestSubscribeOnTopicCallback { private final MqttTestClient client; @@ -361,7 +363,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM } @Override - protected void messageArrivedOnAwaitSubTopic(String requestTopic, MqttMessage mqttMessage) { + public void messageArrived(String requestTopic, MqttMessage mqttMessage) { log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); if (awaitSubTopic.equals(requestTopic)) { qoS = mqttMessage.getQos(); @@ -380,6 +382,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM subscribeLatch.countDown(); } } + } protected byte[] processProtoMessageArrived(String requestTopic, MqttMessage mqttMessage) throws MqttException, InvalidProtocolBufferException { @@ -446,7 +449,7 @@ public abstract class AbstractMqttServerSideRpcIntegrationTest extends AbstractM @Override public void messageArrived(String requestTopic, MqttMessage mqttMessage) { - log.warn("messageArrived on topic: {}, awaitSubTopic: {}", requestTopic, awaitSubTopic); + log.warn("messageArrived on topic: {}", requestTopic); expected.add(new String(mqttMessage.getPayload())); String responseTopic = requestTopic.replace("request", "response"); qoS = mqttMessage.getQos(); diff --git a/application/src/test/resources/logback-test.xml b/application/src/test/resources/logback-test.xml index 953b7094a4..14db2eea7b 100644 --- a/application/src/test/resources/logback-test.xml +++ b/application/src/test/resources/logback-test.xml @@ -28,6 +28,12 @@ + + + + + + diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java index 3caaba0ba9..f70967b72d 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java @@ -561,18 +561,19 @@ public class DefaultCoapClientContext implements CoapClientContext { @Override public void onToDeviceRpcRequest(UUID sessionId, TransportProtos.ToDeviceRpcRequestMsg msg) { - log.trace("[{}] Received RPC command to device", sessionId); + DeviceId deviceId = state.getDeviceId(); + log.trace("[{}][{}] Received RPC command to device: {}", deviceId, sessionId, msg); if (!isDownlinkAllowed(state)) { - log.trace("[{}] ignore downlink request cause client is sleeping.", state.getDeviceId()); + log.trace("[{}][{}] ignore downlink request cause client is sleeping.", deviceId, sessionId); return; } boolean sent = false; String error = null; boolean conRequest = AbstractSyncSessionCallback.isConRequest(state.getRpc()); + int requestId = getNextMsgId(); try { Response response = state.getAdaptor().convertToPublish(msg, state.getConfiguration().getRpcRequestDynamicMessageBuilder()); response.setConfirmable(conRequest); - int requestId = getNextMsgId(); response.setMID(requestId); if (conRequest) { PowerMode powerMode = state.getPowerMode(); @@ -591,6 +592,7 @@ public class DefaultCoapClientContext implements CoapClientContext { transportContext.getScheduler().schedule(() -> { TransportProtos.ToDeviceRpcRequestMsg rpcRequestMsg = transportContext.getRpcAwaitingAck().remove(requestId); if (rpcRequestMsg != null) { + log.trace("[{}][{}][{}] Going to send to device actor RPC request TIMEOUT status update due to server timeout ...", deviceId, sessionId, requestId); transportService.process(state.getSession(), msg, RpcStatus.TIMEOUT, TransportServiceCallback.EMPTY); } }, Math.min(getTimeout(state, powerMode, profileSettings), msg.getExpirationTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS); @@ -598,11 +600,13 @@ public class DefaultCoapClientContext implements CoapClientContext { response.addMessageObserver(new TbCoapMessageObserver(requestId, id -> { TransportProtos.ToDeviceRpcRequestMsg rpcRequestMsg = transportContext.getRpcAwaitingAck().remove(id); if (rpcRequestMsg != null) { + log.trace("[{}][{}][{}] Going to send to device actor RPC request DELIVERED status update ...", deviceId, sessionId, requestId); transportService.process(state.getSession(), rpcRequestMsg, RpcStatus.DELIVERED, true, TransportServiceCallback.EMPTY); } }, id -> { TransportProtos.ToDeviceRpcRequestMsg rpcRequestMsg = transportContext.getRpcAwaitingAck().remove(id); if (rpcRequestMsg != null) { + log.trace("[{}][{}][{}] Going to send to device actor RPC request TIMEOUT status update ...", deviceId, sessionId, requestId); transportService.process(state.getSession(), msg, RpcStatus.TIMEOUT, TransportServiceCallback.EMPTY); } })); @@ -626,8 +630,10 @@ public class DefaultCoapClientContext implements CoapClientContext { .setRequestId(msg.getRequestId()).setError(error).build(), TransportServiceCallback.EMPTY); } else if (sent) { if (!conRequest) { + log.trace("[{}][{}][{}] Going to send to device actor non-confirmable RPC request DELIVERED status update ...", deviceId, sessionId, requestId); transportService.process(state.getSession(), msg, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY); } else if (msg.getPersisted()) { + log.trace("[{}][{}][{}] Going to send to device actor RPC request SENT status update ...", deviceId, sessionId, requestId); transportService.process(state.getSession(), msg, RpcStatus.SENT, TransportServiceCallback.EMPTY); } } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 621504564f..6267ae9424 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -1273,11 +1273,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement public void sendToDeviceRpcRequest(MqttMessage payload, TransportProtos.ToDeviceRpcRequestMsg rpcRequest, TransportProtos.SessionInfoProto sessionInfo) { int msgId = ((MqttPublishMessage) payload).variableHeader().packetId(); + int requestId = rpcRequest.getRequestId(); if (isAckExpected(payload)) { rpcAwaitingAck.put(msgId, rpcRequest); context.getScheduler().schedule(() -> { TransportProtos.ToDeviceRpcRequestMsg msg = rpcAwaitingAck.remove(msgId); if (msg != null) { + log.trace("[{}][{}][{}] Going to send to device actor RPC request TIMEOUT status update ...", deviceSessionCtx.getDeviceId(), sessionId, requestId); transportService.process(sessionInfo, rpcRequest, RpcStatus.TIMEOUT, TransportServiceCallback.EMPTY); } }, Math.max(0, Math.min(deviceSessionCtx.getContext().getTimeout(), rpcRequest.getExpirationTime() - System.currentTimeMillis())), TimeUnit.MILLISECONDS); @@ -1286,18 +1288,20 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement cf.addListener(result -> { Throwable throwable = result.cause(); if (throwable != null) { - log.trace("[{}][{}][{}] Failed send RPC request to device due to: ", deviceSessionCtx.getDeviceId(), sessionId, rpcRequest.getRequestId(), throwable); - this.sendErrorRpcResponse(sessionInfo, rpcRequest.getRequestId(), + log.trace("[{}][{}][{}] Failed send RPC request to device due to: ", deviceSessionCtx.getDeviceId(), sessionId, requestId, throwable); + this.sendErrorRpcResponse(sessionInfo, requestId, ThingsboardErrorCode.INVALID_ARGUMENTS, " Failed send To Device Rpc Request: " + rpcRequest.getMethodName()); return; } if (!isAckExpected(payload)) { + log.trace("[{}][{}][{}] Going to send to device actor RPC request DELIVERED status update ...", deviceSessionCtx.getDeviceId(), sessionId, requestId); transportService.process(sessionInfo, rpcRequest, RpcStatus.DELIVERED, TransportServiceCallback.EMPTY); } else if (rpcRequest.getPersisted()) { + log.trace("[{}][{}][{}] Going to send to device actor RPC request SENT status update ...", deviceSessionCtx.getDeviceId(), sessionId, requestId); transportService.process(sessionInfo, rpcRequest, RpcStatus.SENT, TransportServiceCallback.EMPTY); } if (sparkplugSessionHandler != null) { - this.sendSuccessRpcResponse(sessionInfo, rpcRequest.getRequestId(), ResponseCode.CONTENT, "Success: " + rpcRequest.getMethodName()); + this.sendSuccessRpcResponse(sessionInfo, requestId, ResponseCode.CONTENT, "Success: " + rpcRequest.getMethodName()); } }); } From 9899b8d9f4e6564c4365df0f05c08cdcee9f8153 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 7 Jun 2023 15:24:33 +0300 Subject: [PATCH 140/207] reverted logic to set RPC status SUCCESSFUL even if it undelivered --- .../actors/device/DeviceActorMessageProcessor.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 71d3d43e00..477e161ae1 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -594,19 +594,11 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso boolean delivered = requestMd.isDelivered(); boolean hasError = StringUtils.isNotEmpty(responseMsg.getError()); try { - String payload; - if (hasError) { - payload = responseMsg.getError(); - } else if (delivered) { - payload = responseMsg.getPayload(); - } else { - payload = "Received response for undelivered RPC: " + responseMsg.getPayload(); - } + String payload = hasError ? responseMsg.getError() : responseMsg.getPayload(); systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor( - new FromDeviceRpcResponse(toDeviceRequestMsg.getId(), - payload, null)); + new FromDeviceRpcResponse(toDeviceRequestMsg.getId(), payload, null)); if (toDeviceRequestMsg.isPersisted()) { - RpcStatus status = hasError || !delivered ? RpcStatus.FAILED : RpcStatus.SUCCESSFUL; + RpcStatus status = hasError ? RpcStatus.FAILED : RpcStatus.SUCCESSFUL; JsonNode response; try { response = JacksonUtil.toJsonNode(payload); From 87786ef72d8a08299083c9d05257b5d37a33fbc3 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 7 Jun 2023 15:27:44 +0300 Subject: [PATCH 141/207] refactoring --- .../controller/ControllerConstants.java | 2 +- .../controller/TbResourceController.java | 2 +- .../sql/BaseTbResourceServiceTest.java | 42 +++++++++---------- .../server/common/data/ResourceType.java | 25 +++-------- 4 files changed, 27 insertions(+), 44 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index a8cc2c1043..1cb794c2ec 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java @@ -140,7 +140,7 @@ public class ControllerConstants { protected static final String RESOURCE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the resource title."; protected static final String RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, resourceType, tenantId"; - protected static final String RESOURCE_TYPE_PROPERTY_ALLOWABLE_VALUES = "lwm2m, jks, pkcs12, js"; + protected static final String RESOURCE_TYPE_PROPERTY_ALLOWABLE_VALUES = "LWM2M_MODEL, JKS, PKCS_12, JS_MODULE"; protected static final String RESOURCE_TYPE = "A string value representing the resource type."; protected static final String LWM2M_OBJECT_DESCRIPTION = "LwM2M Object is a object that includes information about the LwM2M model which can be used in transport configuration for the LwM2M device profile. "; diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index 6e8977a886..7bd1000443 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -212,7 +212,7 @@ public class TbResourceController extends BaseController { TbResourceInfoFilter.TbResourceInfoFilterBuilder filter = TbResourceInfoFilter.builder(); filter.tenantId(getTenantId()); if (StringUtils.isNotEmpty(resourceType)){ - filter.resourceType(ResourceType.getResourceByType(resourceType)); + filter.resourceType(ResourceType.valueOf(resourceType)); } if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { return checkNotNull(resourceService.findTenantResourcesByTenantId(filter.build(), pageLink)); diff --git a/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java b/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java index e5183ba8b3..6f08e47412 100644 --- a/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/resource/sql/BaseTbResourceServiceTest.java @@ -105,6 +105,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { ""; private static final String DEFAULT_FILE_NAME = "test.jks"; + private static final String TEST_DATA = "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLQpGSUxFIElORk9STUFUSU9OCgpPTUEgUGVybWFuZW50IERvY3VtZW50CiAgIEZpbGU6IE9NQS1TVVAtTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci1WMV8wXzEtMjAxOTAyMjEtQQogICBUeXBlOiB4bWwKClB1YmxpYyBSZWFjaGFibGUgSW5mb3JtYXRpb24KICAgUGF0aDogaHR0cDovL3d3dy5vcGVubW9iaWxlYWxsaWFuY2Uub3JnL3RlY2gvcHJvZmlsZXMKICAgTmFtZTogTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci12MV8wXzEueG1sCgpOT1JNQVRJVkUgSU5GT1JNQVRJT04KCiAgSW5mb3JtYXRpb24gYWJvdXQgdGhpcyBmaWxlIGNhbiBiZSBmb3VuZCBpbiB0aGUgbGF0ZXN0IHJldmlzaW9uIG9mCgogIE9NQS1UUy1MV00yTV9CaW5hcnlBcHBEYXRhQ29udGFpbmVyLVYxXzBfMQoKICBUaGlzIGlzIGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm9wZW5tb2JpbGVhbGxpYW5jZS5vcmcvCgogIFNlbmQgY29tbWVudHMgdG8gaHR0cHM6Ly9naXRodWIuY29tL09wZW5Nb2JpbGVBbGxpYW5jZS9PTUFfTHdNMk1fZm9yX0RldmVsb3BlcnMvaXNzdWVzCgpDSEFOR0UgSElTVE9SWQoKMTUwNjIwMTggU3RhdHVzIGNoYW5nZWQgdG8gQXBwcm92ZWQgYnkgRE0sIERvYyBSZWYgIyBPTUEtRE0mU0UtMjAxOC0wMDYxLUlOUF9MV00yTV9BUFBEQVRBX1YxXzBfRVJQX2Zvcl9maW5hbF9BcHByb3ZhbAoyMTAyMjAxOSBTdGF0dXMgY2hhbmdlZCB0byBBcHByb3ZlZCBieSBJUFNPLCBEb2MgUmVmICMgT01BLUlQU08tMjAxOS0wMDI1LUlOUF9Md00yTV9PYmplY3RfQXBwX0RhdGFfQ29udGFpbmVyXzFfMF8xX2Zvcl9GaW5hbF9BcHByb3ZhbAoKTEVHQUwgRElTQ0xBSU1FUgoKQ29weXJpZ2h0IDIwMTkgT3BlbiBNb2JpbGUgQWxsaWFuY2UuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCmFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodApub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCjIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Cm5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cwpjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwoiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVApMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUwpGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULApJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCkxJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOCkFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQpQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KClRoZSBhYm92ZSBsaWNlbnNlIGlzIHVzZWQgYXMgYSBsaWNlbnNlIHVuZGVyIGNvcHlyaWdodCBvbmx5LiBQbGVhc2UKcmVmZXJlbmNlIHRoZSBPTUEgSVBSIFBvbGljeSBmb3IgcGF0ZW50IGxpY2Vuc2luZyB0ZXJtczoKaHR0cHM6Ly93d3cub21hc3BlY3dvcmtzLm9yZy9hYm91dC9pbnRlbGxlY3R1YWwtcHJvcGVydHktcmlnaHRzLwoKLS0+CjxMV00yTSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj0iaHR0cDovL29wZW5tb2JpbGVhbGxpYW5jZS5vcmcvdGVjaC9wcm9maWxlcy9MV00yTS54c2QiPgoJPE9iamVjdCBPYmplY3RUeXBlPSJNT0RlZmluaXRpb24iPgoJCTxOYW1lPkJpbmFyeUFwcERhdGFDb250YWluZXI8L05hbWU+CgkJPERlc2NyaXB0aW9uMT48IVtDREFUQVtUaGlzIEx3TTJNIE9iamVjdHMgcHJvdmlkZXMgdGhlIGFwcGxpY2F0aW9uIHNlcnZpY2UgZGF0YSByZWxhdGVkIHRvIGEgTHdNMk0gU2VydmVyLCBlZy4gV2F0ZXIgbWV0ZXIgZGF0YS4gClRoZXJlIGFyZSBzZXZlcmFsIG1ldGhvZHMgdG8gY3JlYXRlIGluc3RhbmNlIHRvIGluZGljYXRlIHRoZSBtZXNzYWdlIGRpcmVjdGlvbiBiYXNlZCBvbiB0aGUgbmVnb3RpYXRpb24gYmV0d2VlbiBBcHBsaWNhdGlvbiBhbmQgTHdNMk0uIFRoZSBDbGllbnQgYW5kIFNlcnZlciBzaG91bGQgbmVnb3RpYXRlIHRoZSBpbnN0YW5jZShzKSB1c2VkIHRvIGV4Y2hhbmdlIHRoZSBkYXRhLiBGb3IgZXhhbXBsZToKIC0gVXNpbmcgYSBzaW5nbGUgaW5zdGFuY2UgZm9yIGJvdGggZGlyZWN0aW9ucyBjb21tdW5pY2F0aW9uLCBmcm9tIENsaWVudCB0byBTZXJ2ZXIgYW5kIGZyb20gU2VydmVyIHRvIENsaWVudC4KIC0gVXNpbmcgYW4gaW5zdGFuY2UgZm9yIGNvbW11bmljYXRpb24gZnJvbSBDbGllbnQgdG8gU2VydmVyIGFuZCBhbm90aGVyIG9uZSBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIFNlcnZlciB0byBDbGllbnQKIC0gVXNpbmcgc2V2ZXJhbCBpbnN0YW5jZXMKXV0+PC9EZXNjcmlwdGlvbjE+CgkJPE9iamVjdElEPjE5PC9PYmplY3RJRD4KCQk8T2JqZWN0VVJOPnVybjpvbWE6bHdtMm06b21hOjE5PC9PYmplY3RVUk4+CgkJPExXTTJNVmVyc2lvbj4xLjA8L0xXTTJNVmVyc2lvbj4KCQk8T2JqZWN0VmVyc2lvbj4xLjA8L09iamVjdFZlcnNpb24+CgkJPE11bHRpcGxlSW5zdGFuY2VzPk11bHRpcGxlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJPFJlc291cmNlcz4KCQkJPEl0ZW0gSUQ9IjAiPjxOYW1lPkRhdGE8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5NdWx0aXBsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk1hbmRhdG9yeTwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+T3BhcXVlPC9UeXBlPgoJCQkJPFJhbmdlRW51bWVyYXRpb24gLz4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBjb250ZW50Ll1dPjwvRGVzY3JpcHRpb24+CgkJCTwvSXRlbT4KCQkJPEl0ZW0gSUQ9IjEiPjxOYW1lPkRhdGEgUHJpb3JpdHk8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5TaW5nbGU8L011bHRpcGxlSW5zdGFuY2VzPgoJCQkJPE1hbmRhdG9yeT5PcHRpb25hbDwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+SW50ZWdlcjwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjEgYnl0ZXM8L1JhbmdlRW51bWVyYXRpb24+CgkJCQk8VW5pdHMgLz4KCQkJCTxEZXNjcmlwdGlvbj48IVtDREFUQVtJbmRpY2F0ZXMgdGhlIEFwcGxpY2F0aW9uIGRhdGEgcHJpb3JpdHk6CjA6SW1tZWRpYXRlCjE6QmVzdEVmZm9ydAoyOkxhdGVzdAozLTEwMDogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCjEwMS0yNTQ6IFByb3ByaWV0YXJ5IG1vZGUuXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iMiI+PE5hbWU+RGF0YSBDcmVhdGlvbiBUaW1lPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlRpbWU8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbiAvPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBEYXRhIGluc3RhbmNlIGNyZWF0aW9uIHRpbWVzdGFtcC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSIzIj48TmFtZT5EYXRhIERlc2NyaXB0aW9uPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlN0cmluZzwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjMyIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkYXRhIGRlc2NyaXB0aW9uLgplLmcuICJtZXRlciByZWFkaW5nIi5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSI0Ij48TmFtZT5EYXRhIEZvcm1hdDwvTmFtZT4KCQkJCTxPcGVyYXRpb25zPlJXPC9PcGVyYXRpb25zPgoJCQkJPE11bHRpcGxlSW5zdGFuY2VzPlNpbmdsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJCQk8VHlwZT5TdHJpbmc8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4zMiBieXRlczwvUmFuZ2VFbnVtZXJhdGlvbj4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgZm9ybWF0IG9mIHRoZSBBcHBsaWNhdGlvbiBEYXRhLgplLmcuIFlHLU1ldGVyLVdhdGVyLVJlYWRpbmcKVVRGOC1zdHJpbmcKXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iNSI+PE5hbWU+QXBwIElEPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPkludGVnZXI8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4yIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkZXN0aW5hdGlvbiBBcHBsaWNhdGlvbiBJRC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+PC9SZXNvdXJjZXM+CgkJPERlc2NyaXB0aW9uMj48IVtDREFUQVtdXT48L0Rlc2NyaXB0aW9uMj4KCTwvT2JqZWN0Pgo8L0xXTTJNPgo="; private IdComparator idComparator = new IdComparator<>(); @@ -147,7 +148,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { @Test public void testSaveResourceWithMaxSumDataSizeOutOfLimit() throws Exception { loginSysAdmin(); - long limit = 1; + long limit = 4; EntityInfo defaultTenantProfileInfo = doGet("/api/tenantProfileInfo/default", EntityInfo.class); TenantProfile defaultTenantProfile = doGet("/api/tenantProfile/" + defaultTenantProfileInfo.getId().getId().toString(), TenantProfile.class); defaultTenantProfile.getProfileData().setConfiguration(DefaultTenantProfileConfiguration.builder().maxResourcesInBytes(limit).build()); @@ -159,7 +160,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { createResource("test", DEFAULT_FILE_NAME); - assertEquals(1, resourceService.sumDataSizeByTenantId(tenantId)); + assertEquals(4, resourceService.sumDataSizeByTenantId(tenantId)); try { assertThatThrownBy(() -> createResource("test1", 1 + DEFAULT_FILE_NAME)) @@ -177,16 +178,12 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { assertEquals(0, resourceService.sumDataSizeByTenantId(tenantId)); createResource("test", DEFAULT_FILE_NAME); - assertEquals(1, resourceService.sumDataSizeByTenantId(tenantId)); + assertEquals(4, resourceService.sumDataSizeByTenantId(tenantId)); - int maxSumDataSize = 8; - - for (int i = 2; i <= maxSumDataSize; i++) { + for (int i = 2; i < 4; i++) { createResource("test" + i, i + DEFAULT_FILE_NAME); - assertEquals(i, resourceService.sumDataSizeByTenantId(tenantId)); + assertEquals(i*4, resourceService.sumDataSizeByTenantId(tenantId)); } - - assertEquals(maxSumDataSize, resourceService.sumDataSizeByTenantId(tenantId)); } private TbResource createResource(String title, String filename) throws Exception { @@ -195,7 +192,8 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle(title); resource.setResourceType(ResourceType.JKS); resource.setFileName(filename); - resource.setData("1"); + byte[] b = new byte[1]; + resource.setData(Base64.getEncoder().encodeToString(b)); return resourceService.save(resource); } @@ -206,7 +204,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My first resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = resourceService.save(resource); @@ -254,7 +252,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = resourceService.save(resource); assertEquals(TenantId.SYS_TENANT_ID, savedResource.getTenantId()); @@ -269,7 +267,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = resourceService.save(resource); @@ -278,7 +276,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); try { Assertions.assertThrows(DataValidationException.class, () -> { @@ -295,7 +293,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTenantId(tenantId); resource.setResourceType(ResourceType.JKS); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); Assertions.assertThrows(DataValidationException.class, () -> { resourceService.save(resource); }); @@ -308,7 +306,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); Assertions.assertThrows(DataValidationException.class, () -> { resourceService.save(resource); }); @@ -335,7 +333,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = resourceService.save(resource); TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId()); @@ -351,7 +349,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTenantId(tenantId); resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = resourceService.save(resource); TbResource foundResource = resourceService.getResource(tenantId, savedResource.getResourceType(), savedResource.getResourceKey()); @@ -366,7 +364,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setResourceType(ResourceType.JKS); resource.setTitle("My resource"); resource.setFileName(DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResource savedResource = resourceService.save(resource); TbResource foundResource = resourceService.findResourceById(tenantId, savedResource.getId()); @@ -392,7 +390,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle("Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); resources.add(new TbResourceInfo(resourceService.save(resource))); } @@ -446,7 +444,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle("System Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); TbResourceInfo tbResourceInfo = new TbResourceInfo(resourceService.save(resource)); if (i >= 50) { resources.add(tbResourceInfo); @@ -459,7 +457,7 @@ public class BaseTbResourceServiceTest extends AbstractControllerTest { resource.setTitle("Tenant Resource" + i); resource.setResourceType(ResourceType.JKS); resource.setFileName(i + DEFAULT_FILE_NAME); - resource.setData("Test Data"); + resource.setData(TEST_DATA); resources.add(new TbResourceInfo(resourceService.save(resource))); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java index b67cd49aff..81be6a1e41 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java @@ -16,33 +16,18 @@ package org.thingsboard.server.common.data; public enum ResourceType { - LWM2M_MODEL("lwm2m", "application/xml"), - JKS("jks", "application/x-java-keystore"), - PKCS_12("pkcs12", "application/x-pkcs12"), - JS_MODULE("js", "application/javascript"); + LWM2M_MODEL("application/xml"), + JKS("application/x-java-keystore"), + PKCS_12("application/x-pkcs12"), + JS_MODULE("application/javascript"); - private final String type; private final String mediaType; - ResourceType(String type, String mediaType) { - this.type = type; + ResourceType(String mediaType) { this.mediaType = mediaType; } - public static ResourceType getResourceByType(String type) { - for(ResourceType resourceType : values()) { - if (resourceType.getType().equalsIgnoreCase(type)) { - return resourceType; - } - } - throw new IllegalArgumentException(); - } - public String getMediaType() { return mediaType; } - - public String getType() { - return type; - } } From 1bde8d3dffa5ea07c6946d701427fc1b3805b193 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 7 Jun 2023 15:37:47 +0300 Subject: [PATCH 142/207] UI: Added support js module resource in widget/action --- ui-ngx/package.json | 4 +- ui-ngx/src/app/core/http/resource.service.ts | 16 +- .../app/core/services/resources.service.ts | 32 +++- ui-ngx/src/app/modules/common/modules-map.ts | 7 + ...ction-pretty-resources-tabs.component.html | 32 ++-- .../modules/home/pages/admin/admin.module.ts | 2 + .../resources-library-table-config.resolve.ts | 7 +- .../resource/resources-library.component.ts | 4 +- .../resources-table-header.component.html | 30 +++ .../resources-table-header.component.ts | 42 ++++ .../pages/widget/widget-editor.component.html | 31 +-- .../pages/widget/widget-editor.component.scss | 27 +-- .../src/app/shared/components/public-api.ts | 1 + .../resource-autocomplete.component.html | 46 +++++ .../resource-autocomplete.component.ts | 179 ++++++++++++++++++ .../src/app/shared/models/resource.models.ts | 3 +- ui-ngx/src/app/shared/shared.module.ts | 3 + .../assets/locale/locale.constant-en_US.json | 1 + ui-ngx/yarn.lock | 16 +- 19 files changed, 419 insertions(+), 64 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/pages/admin/resource/resources-table-header.component.html create mode 100644 ui-ngx/src/app/modules/home/pages/admin/resource/resources-table-header.component.ts create mode 100644 ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.html create mode 100644 ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.ts diff --git a/ui-ngx/package.json b/ui-ngx/package.json index ed096b871a..4112e24fce 100644 --- a/ui-ngx/package.json +++ b/ui-ngx/package.json @@ -96,7 +96,7 @@ "schema-inspector": "^2.0.2", "screenfull": "^6.0.2", "split.js": "^1.6.5", - "systemjs": "6.11.0", + "systemjs": "6.14.1", "tinycolor2": "^1.6.0", "tinymce": "~5.10.7", "tooltipster": "^4.2.8", @@ -137,7 +137,7 @@ "@types/raphael": "^2.3.2", "@types/react": "17.0.37", "@types/react-dom": "17.0.11", - "@types/systemjs": "6.1.1", + "@types/systemjs": "6.13.1", "@types/tinycolor2": "^1.4.3", "@types/tooltipster": "^0.0.31", "@typescript-eslint/eslint-plugin": "5.57.0", diff --git a/ui-ngx/src/app/core/http/resource.service.ts b/ui-ngx/src/app/core/http/resource.service.ts index 9296f701b0..f7cb8441d1 100644 --- a/ui-ngx/src/app/core/http/resource.service.ts +++ b/ui-ngx/src/app/core/http/resource.service.ts @@ -20,8 +20,9 @@ import { PageLink } from '@shared/models/page/page-link'; import { defaultHttpOptionsFromConfig, RequestConfig } from '@core/http/http-utils'; import { forkJoin, Observable, of } from 'rxjs'; import { PageData } from '@shared/models/page/page-data'; -import { Resource, ResourceInfo } from '@shared/models/resource.models'; +import { Resource, ResourceInfo, ResourceType } from '@shared/models/resource.models'; import { catchError, map, mergeMap } from 'rxjs/operators'; +import { isNotEmptyStr } from '@core/utils'; @Injectable({ providedIn: 'root' @@ -33,15 +34,22 @@ export class ResourceService { } - public getResources(pageLink: PageLink, config?: RequestConfig): Observable> { - return this.http.get>(`/api/resource${pageLink.toQuery()}`, - defaultHttpOptionsFromConfig(config)); + public getResources(pageLink: PageLink, resourceType?: ResourceType, config?: RequestConfig): Observable> { + let url = `/api/resource${pageLink.toQuery()}`; + if (isNotEmptyStr(resourceType)) { + url += `&resourceType=${resourceType}`; + } + return this.http.get>(url, defaultHttpOptionsFromConfig(config)); } public getResource(resourceId: string, config?: RequestConfig): Observable { return this.http.get(`/api/resource/${resourceId}`, defaultHttpOptionsFromConfig(config)); } + public getResourceInfo(resourceId: string, config?: RequestConfig): Observable { + return this.http.get(`/api/resource/info/${resourceId}`, defaultHttpOptionsFromConfig(config)); + } + public downloadResource(resourceId: string): Observable { return this.http.get(`/api/resource/${resourceId}/download`, { responseType: 'arraybuffer', diff --git a/ui-ngx/src/app/core/services/resources.service.ts b/ui-ngx/src/app/core/services/resources.service.ts index b34cec5eb0..5dc20ddd46 100644 --- a/ui-ngx/src/app/core/services/resources.service.ts +++ b/ui-ngx/src/app/core/services/resources.service.ts @@ -27,6 +27,9 @@ import { DOCUMENT } from '@angular/common'; import { forkJoin, Observable, ReplaySubject, throwError } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { IModulesMap } from '@modules/common/modules-map.models'; +import { TbResourceId } from '@shared/models/id/tb-resource-id'; +import { isObject } from '@core/utils'; +import { AuthService } from '@core/auth/auth.service'; declare const System; @@ -69,16 +72,18 @@ export class ResourcesService { return this.loadResourceByType(fileType, url); } - public loadFactories(url: string, modulesMap: IModulesMap): Observable { + public loadFactories(resourceId: string | TbResourceId, modulesMap: IModulesMap): Observable { + const url = this.getDownloadUrl(resourceId); if (this.loadedModulesAndFactories[url]) { return this.loadedModulesAndFactories[url].asObservable(); } modulesMap.init(); + const meta = this.getMetaInfo(resourceId); const subject = new ReplaySubject(); this.loadedModulesAndFactories[url] = subject; import('@angular/compiler').then( () => { - System.import(url).then( + System.import(url, undefined, meta).then( (module) => { const modules = this.extractNgModules(module); if (modules.length) { @@ -123,16 +128,18 @@ export class ResourcesService { return subject.asObservable(); } - public loadModules(url: string, modulesMap: IModulesMap): Observable[]> { + public loadModules(resourceId: string | TbResourceId, modulesMap: IModulesMap): Observable[]> { + const url = this.getDownloadUrl(resourceId); if (this.loadedModules[url]) { return this.loadedModules[url].asObservable(); } modulesMap.init(); + const meta = this.getMetaInfo(resourceId); const subject = new ReplaySubject[]>(); this.loadedModules[url] = subject; import('@angular/compiler').then( () => { - System.import(url).then( + System.import(url, undefined, meta).then( (module) => { try { let modules; @@ -246,4 +253,21 @@ export class ResourcesService { this.anchor.appendChild(el); return subject.asObservable(); } + + private getDownloadUrl(resourceId: string | TbResourceId): string { + if (isObject(resourceId)) { + return `/api/resource/js/${(resourceId as TbResourceId).id}/download`; + } + return resourceId as string; + } + + private getMetaInfo(resourceId: string | TbResourceId): object { + if (isObject(resourceId)) { + return { + additionalHeaders: { + 'X-Authorization': `Bearer ${AuthService.getJwtToken()}` + } + }; + } + } } diff --git a/ui-ngx/src/app/modules/common/modules-map.ts b/ui-ngx/src/app/modules/common/modules-map.ts index b3a14b0f61..961d34a1d4 100644 --- a/ui-ngx/src/app/modules/common/modules-map.ts +++ b/ui-ngx/src/app/modules/common/modules-map.ts @@ -614,6 +614,13 @@ class ModulesMap implements IModulesMap { for (const moduleId of Object.keys(this.modulesMap)) { System.set('app:' + moduleId, this.modulesMap[moduleId]); } + System.constructor.prototype.shouldFetch = (url: string) => url.endsWith('/download'); + System.constructor.prototype.fetch = (url, options: RequestInit & {meta?: any}) => { + if (options?.meta?.additionalHeaders) { + options.headers = { ...options.headers, ...options.meta.additionalHeaders }; + } + return fetch(url, options); + }; this.initialized = true; } } diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html b/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html index 7014570235..f44ff6138c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html @@ -22,11 +22,14 @@
- - - + + {{ 'widget.resource-is-module' | translate }} @@ -40,16 +43,15 @@ close
-
- -
+
diff --git a/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts b/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts index 02a4bf5867..533fd0fea1 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/admin.module.ts @@ -28,6 +28,7 @@ import { SmsProviderComponent } from '@home/pages/admin/sms-provider.component'; import { SendTestSmsDialogComponent } from '@home/pages/admin/send-test-sms-dialog.component'; import { HomeSettingsComponent } from '@home/pages/admin/home-settings.component'; import { ResourcesLibraryComponent } from '@home/pages/admin/resource/resources-library.component'; +import { ResourcesTableHeaderComponent } from '@home/pages/admin/resource/resources-table-header.component'; import { QueueComponent } from '@home/pages/admin/queue/queue.component'; import { RepositoryAdminSettingsComponent } from '@home/pages/admin/repository-admin-settings.component'; import { AutoCommitAdminSettingsComponent } from '@home/pages/admin/auto-commit-admin-settings.component'; @@ -44,6 +45,7 @@ import { TwoFactorAuthSettingsComponent } from '@home/pages/admin/two-factor-aut OAuth2SettingsComponent, HomeSettingsComponent, ResourcesLibraryComponent, + ResourcesTableHeaderComponent, QueueComponent, RepositoryAdminSettingsComponent, AutoCommitAdminSettingsComponent, diff --git a/ui-ngx/src/app/modules/home/pages/admin/resource/resources-library-table-config.resolve.ts b/ui-ngx/src/app/modules/home/pages/admin/resource/resources-library-table-config.resolve.ts index b3126c781b..733e5ef2b3 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/resource/resources-library-table-config.resolve.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/resource/resources-library-table-config.resolve.ts @@ -36,6 +36,7 @@ import { ResourcesLibraryComponent } from '@home/pages/admin/resource/resources- import { PageLink } from '@shared/models/page/page-link'; import { EntityAction } from '@home/models/entity/entity-component.models'; import { map } from 'rxjs/operators'; +import { ResourcesTableHeaderComponent } from '@home/pages/admin/resource/resources-table-header.component'; @Injectable() export class ResourcesLibraryTableConfigResolver implements Resolve> { @@ -53,6 +54,7 @@ export class ResourcesLibraryTableConfigResolver implements Resolve resource ? resource.title : ''; @@ -81,7 +83,7 @@ export class ResourcesLibraryTableConfigResolver implements Resolve this.translate.instant('resource.delete-resources-title', {count}); this.config.deleteEntitiesContent = () => this.translate.instant('resource.delete-resources-text'); - this.config.entitiesFetchFunction = pageLink => this.resourceService.getResources(pageLink); + this.config.entitiesFetchFunction = pageLink => this.resourceService.getResources(pageLink, this.config.componentsData.resourceType); this.config.loadEntity = id => this.resourceService.getResource(id.id); this.config.saveEntity = resource => this.saveResource(resource); this.config.deleteEntity = id => this.resourceService.deleteResource(id.id); @@ -110,6 +112,9 @@ export class ResourcesLibraryTableConfigResolver implements Resolve { this.config.tableTitle = this.translate.instant('resource.resources-library'); + this.config.componentsData = { + resourceType: '' + }; const authUser = getCurrentAuthUser(this.store); this.config.deleteEnabled = (resource) => this.isResourceEditable(resource, authUser.authority); this.config.entitySelectionEnabled = (resource) => this.isResourceEditable(resource, authUser.authority); diff --git a/ui-ngx/src/app/modules/home/pages/admin/resource/resources-library.component.ts b/ui-ngx/src/app/modules/home/pages/admin/resource/resources-library.component.ts index 90f7847e10..99d8697dc5 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/resource/resources-library.component.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/resource/resources-library.component.ts @@ -57,7 +57,7 @@ export class ResourcesLibraryComponent extends EntityComponent impleme ngOnInit() { super.ngOnInit(); this.entityForm.get('resourceType').valueChanges.pipe( - startWith(ResourceType.LWM2M_MODEL), + startWith(ResourceType.JS_MODULE), filter(() => this.isAdd), takeUntil(this.destroy$) ).subscribe((type) => { @@ -91,7 +91,7 @@ export class ResourcesLibraryComponent extends EntityComponent impleme buildForm(entity: Resource): FormGroup { return this.fb.group({ title: [entity ? entity.title : '', [Validators.required, Validators.maxLength(255)]], - resourceType: [entity?.resourceType ? entity.resourceType : ResourceType.LWM2M_MODEL, Validators.required], + resourceType: [entity?.resourceType ? entity.resourceType : ResourceType.JS_MODULE, Validators.required], fileName: [entity ? entity.fileName : null, Validators.required], data: [entity ? entity.data : null, Validators.required] }); diff --git a/ui-ngx/src/app/modules/home/pages/admin/resource/resources-table-header.component.html b/ui-ngx/src/app/modules/home/pages/admin/resource/resources-table-header.component.html new file mode 100644 index 0000000000..ad8cf063e0 --- /dev/null +++ b/ui-ngx/src/app/modules/home/pages/admin/resource/resources-table-header.component.html @@ -0,0 +1,30 @@ + + + resource.resource-type + + + {{ "resource.all-types" | translate }} + + + {{ resourceTypesTranslationMap.get(resourceType) | translate }} + + + diff --git a/ui-ngx/src/app/modules/home/pages/admin/resource/resources-table-header.component.ts b/ui-ngx/src/app/modules/home/pages/admin/resource/resources-table-header.component.ts new file mode 100644 index 0000000000..dfe4bacff8 --- /dev/null +++ b/ui-ngx/src/app/modules/home/pages/admin/resource/resources-table-header.component.ts @@ -0,0 +1,42 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { EntityTableHeaderComponent } from '@home/components/entity/entity-table-header.component'; +import { Resource, ResourceInfo, ResourceType, ResourceTypeTranslationMap } from '@shared/models/resource.models'; +import { PageLink } from '@shared/models/page/page-link'; + +@Component({ + selector: 'tb-resources-table-header', + templateUrl: './resources-table-header.component.html', + styleUrls: [] +}) +export class ResourcesTableHeaderComponent extends EntityTableHeaderComponent { + + readonly resourceTypes: ResourceType[] = Object.values(ResourceType); + readonly resourceTypesTranslationMap = ResourceTypeTranslationMap; + + constructor(protected store: Store) { + super(store); + } + + resourceTypeChanged(resourceType: ResourceType) { + this.entitiesTableConfig.componentsData.resourceType = resourceType; + this.entitiesTableConfig.getTable().resetSortAndFilter(true); + } +} diff --git a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html index 046ad5acb2..2b650cb1ce 100644 --- a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html +++ b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html @@ -122,12 +122,14 @@
- - - + + {{ 'widget.resource-is-module' | translate }} @@ -140,15 +142,14 @@ close
-
- -
+
diff --git a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.scss b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.scss index 7d0d854d46..b8359b38db 100644 --- a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.scss +++ b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.scss @@ -31,18 +31,21 @@ tb-widget-editor { overflow-y: auto; } - mat-form-field.resource-field { - max-height: 40px; - margin: 10px 0 0; - .mat-mdc-text-field-wrapper { - padding-bottom: 0; - .mat-mdc-form-field-flex { - max-height: 40px; - .mat-mdc-form-field-infix { - border: 0; - padding-top: 7px; - padding-bottom: 7px; - min-height: 32px; + .resource-field { + mat-form-field { + .mat-mdc-text-field-wrapper { + padding-bottom: 0; + height: 40px; + + .mat-mdc-form-field-flex { + max-height: 40px; + + .mat-mdc-form-field-infix { + border: 0; + padding-top: 7px; + padding-bottom: 7px; + min-height: 32px; + } } } } diff --git a/ui-ngx/src/app/shared/components/public-api.ts b/ui-ngx/src/app/shared/components/public-api.ts index 1dd31182f1..9ec226769a 100644 --- a/ui-ngx/src/app/shared/components/public-api.ts +++ b/ui-ngx/src/app/shared/components/public-api.ts @@ -22,4 +22,5 @@ export * from './js-func.component'; export * from './script-lang.component'; export * from './slack-conversation-autocomplete.component'; export * from './notification/template-autocomplete.component'; +export * from './resource/resource-autocomplete.component'; export * from './toggle-header.component'; diff --git a/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.html b/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.html new file mode 100644 index 0000000000..bd7a2016d0 --- /dev/null +++ b/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.html @@ -0,0 +1,46 @@ + + + + + + + + + + {{ searchText }} + + + diff --git a/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.ts b/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.ts new file mode 100644 index 0000000000..6debdb49d9 --- /dev/null +++ b/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.ts @@ -0,0 +1,179 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; +import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { coerceBoolean } from '@shared/decorators/coercion'; +import { Observable, of } from 'rxjs'; +import { catchError, debounceTime, map, share, switchMap, tap } from 'rxjs/operators'; +import { isDefinedAndNotNull, isEmptyStr, isEqual, isObject } from '@core/utils'; +import { ResourceInfo, ResourceType } from '@shared/models/resource.models'; +import { TbResourceId } from '@shared/models/id/tb-resource-id'; +import { ResourceService } from '@core/http/resource.service'; +import { PageLink } from '@shared/models/page/page-link'; +import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field'; + +@Component({ + selector: 'tb-resource-autocomplete', + templateUrl: './resource-autocomplete.component.html', + styleUrls: [], + providers: [{ + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => ResourceAutocompleteComponent), + multi: true + }] +}) +export class ResourceAutocompleteComponent implements ControlValueAccessor, OnInit { + + @Input() + @coerceBoolean() + disabled: boolean; + + @Input() + @coerceBoolean() + required: boolean; + + @Input() + appearance: MatFormFieldAppearance = 'fill'; + + @Input() + subscriptSizing: SubscriptSizing = 'fixed'; + + @Input() + placeholder: string; + + @Input() + @coerceBoolean() + hideRequiredMarker = false; + + @Input() + @coerceBoolean() + allowAutocomplete = false; + + resourceFormGroup = this.fb.group({ + resource: [null] + }); + + filteredResources$: Observable>; + + searchText = ''; + + @ViewChild('resourceInput', {static: true}) resourceInput: ElementRef; + + private modelValue: string | TbResourceId; + private dirty = false; + + private propagateChange = (v: any) => { }; + + constructor(private fb: FormBuilder, + private resourceService: ResourceService) { + } + + ngOnInit(): void { + if(this.required) { + this.resourceFormGroup.get('resource').setValidators(Validators.required); + this.resourceFormGroup.get('resource').updateValueAndValidity({emitEvent: false}); + } + this.filteredResources$ = this.resourceFormGroup.get('resource').valueChanges + .pipe( + debounceTime(150), + tap(value => { + let modelValue; + if (isObject(value)) { + modelValue = value.id; + } else if (isEmptyStr(value)) { + modelValue = null; + } else { + modelValue = value; + } + this.updateView(modelValue); + if (value === null) { + this.clear(); + } + }), + map(value => value ? (typeof value === 'string' ? value : value.title) : ''), + switchMap(name => this.fetchResources(name) ), + share() + ); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean) { + this.disabled = isDisabled; + if (this.disabled) { + this.resourceFormGroup.disable({emitEvent: false}); + } else { + this.resourceFormGroup.enable({emitEvent: false}); + } + } + + writeValue(value: string | TbResourceId) { + if (isDefinedAndNotNull(value)) { + this.searchText = ''; + if (isObject(value) && typeof value !== 'string' && (value as TbResourceId).id) { + this.resourceService.getResourceInfo(value.id, {ignoreLoading: true, ignoreErrors: true}).subscribe(resource => { + this.modelValue = resource.id; + this.resourceFormGroup.get('resource').patchValue(resource, {emitEvent: false}); + }); + } else { + this.modelValue = value; + this.resourceFormGroup.get('resource').patchValue(value, {emitEvent: false}); + } + this.dirty = true; + } + } + + displayResourceFn(resource?: ResourceInfo | string): string { + return isObject(resource) ? (resource as ResourceInfo).title : resource as string; + } + + clear() { + this.resourceFormGroup.get('resource').patchValue('', {emitEvent: true}); + setTimeout(() => { + this.resourceInput.nativeElement.blur(); + this.resourceInput.nativeElement.focus(); + }, 0); + } + + onFocus() { + if (this.dirty) { + this.resourceFormGroup.get('resource').updateValueAndValidity({onlySelf: true, emitEvent: true}); + this.dirty = false; + } + } + + private updateView(value: string | TbResourceId ) { + if (!isEqual(this.modelValue, value)) { + this.modelValue = value; + this.propagateChange(this.modelValue); + } + } + + private fetchResources(searchText?: string): Observable> { + this.searchText = searchText; + return this.resourceService.getResources(new PageLink(50, 0, searchText), ResourceType.JS_MODULE, {ignoreLoading: true}).pipe( + catchError(() => of(null)), + map(data => data.data) + ); + } + +} diff --git a/ui-ngx/src/app/shared/models/resource.models.ts b/ui-ngx/src/app/shared/models/resource.models.ts index 8d7121c5e5..6621f10c42 100644 --- a/ui-ngx/src/app/shared/models/resource.models.ts +++ b/ui-ngx/src/app/shared/models/resource.models.ts @@ -52,7 +52,7 @@ export const ResourceTypeTranslationMap = new Map( ] ); -export interface ResourceInfo extends BaseData { +export interface ResourceInfo extends Omit, 'name' | 'label'> { tenantId?: TenantId; resourceKey?: string; title?: string; @@ -62,6 +62,7 @@ export interface ResourceInfo extends BaseData { export interface Resource extends ResourceInfo { data: string; fileName: string; + name?: string; } export interface Resources extends ResourceInfo { diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts index 1d755c3bb1..7806c9c15b 100644 --- a/ui-ngx/src/app/shared/shared.module.ts +++ b/ui-ngx/src/app/shared/shared.module.ts @@ -189,6 +189,7 @@ import { GtMdLgShowHideDirective } from '@shared/layout/layout.directives'; import { ColorPickerComponent } from '@shared/components/color-picker/color-picker.component'; +import { ResourceAutocompleteComponent } from '@shared/components/resource/resource-autocomplete.component'; import { ShortNumberPipe } from '@shared/pipe/short-number.pipe'; import { ToggleHeaderComponent } from '@shared/components/toggle-header.component'; @@ -360,6 +361,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) GtMdLgLayoutGapDirective, GtMdLgShowHideDirective, ColorPickerComponent, + ResourceAutocompleteComponent, ToggleHeaderComponent ], imports: [ @@ -586,6 +588,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) GtMdLgLayoutGapDirective, GtMdLgShowHideDirective, ColorPickerComponent, + ResourceAutocompleteComponent, ToggleHeaderComponent ] }) 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 ea9230cf34..345d31067a 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3252,6 +3252,7 @@ }, "resource": { "add": "Add Resource", + "all-types": "All", "copyId": "Copy resource Id", "delete": "Delete resource", "delete-resource-text": "Be careful, after the confirmation the resource will become unrecoverable.", diff --git a/ui-ngx/yarn.lock b/ui-ngx/yarn.lock index 8da9cb382a..2ff2c81163 100644 --- a/ui-ngx/yarn.lock +++ b/ui-ngx/yarn.lock @@ -3286,10 +3286,10 @@ dependencies: "@types/react" "*" -"@types/systemjs@6.1.1": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@types/systemjs/-/systemjs-6.1.1.tgz#eae17f2a080e867d01a2dd614f524ab227cf5a41" - integrity sha512-d1M6eDKBGWx7RbYy295VEFoOF9YDJkPI959QYnmzcmeaV+SP4D0xV7dEh3sN5XF3GvO3PhGzm+17Z598nvHQuQ== +"@types/systemjs@6.13.1": + version "6.13.1" + resolved "https://registry.yarnpkg.com/@types/systemjs/-/systemjs-6.13.1.tgz#fccf8049fdf328bca4cfbad3a9cc7bf088b45048" + integrity sha512-Jxo2/uif1WpkabfyvWpFmPWFPDdwKUmyL7xWzjtxNALEu2pgce+eISjbf0Vr+SsK/D9savO5kTRcf+COLK5eiQ== "@types/tinycolor2@^1.4.3": version "1.4.3" @@ -10101,10 +10101,10 @@ symbol-observable@4.0.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== -systemjs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/systemjs/-/systemjs-6.11.0.tgz#8df8e74fc05822e6c40170aa409b9ca64833315f" - integrity sha512-7YPIY44j+BoY+E6cGBSw0oCU8SNTTIHKZgftcBdwWkDzs/M86Fdlr21FrzAyph7Zo8r3CFGscyFe4rrBtixrBg== +systemjs@6.14.1: + version "6.14.1" + resolved "https://registry.yarnpkg.com/systemjs/-/systemjs-6.14.1.tgz#95a580b91b50d0d69ff178ed4816f0ddbcea23c1" + integrity sha512-8ftwWd+XnQtZ/aGbatrN4QFNGrKJzmbtixW+ODpci7pyoTajg4sonPP8aFLESAcuVxaC1FyDESt+SpfFCH9rZQ== table-layout@^1.0.2: version "1.0.2" From 7ee861d55cd4f8ce25d407abf553db8191f0cbba Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 7 Jun 2023 15:55:47 +0300 Subject: [PATCH 143/207] removed unused methods and variables --- .../server/actors/device/DeviceActor.java | 10 +- .../device/DeviceActorMessageProcessor.java | 130 ++++++++---------- 2 files changed, 66 insertions(+), 74 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java index d5833e0c07..2779a83979 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java @@ -59,10 +59,10 @@ public class DeviceActor extends ContextAwareActor { protected boolean doProcess(TbActorMsg msg) { switch (msg.getMsgType()) { case TRANSPORT_TO_DEVICE_ACTOR_MSG: - processor.process(ctx, (TransportToDeviceActorMsgWrapper) msg); + processor.process((TransportToDeviceActorMsgWrapper) msg); break; case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG: - processor.processAttributesUpdate(ctx, (DeviceAttributesEventNotificationMsg) msg); + processor.processAttributesUpdate((DeviceAttributesEventNotificationMsg) msg); break; case DEVICE_CREDENTIALS_UPDATE_TO_DEVICE_ACTOR_MSG: processor.processCredentialsUpdate(msg); @@ -74,10 +74,10 @@ public class DeviceActor extends ContextAwareActor { processor.processRpcRequest(ctx, (ToDeviceRpcRequestActorMsg) msg); break; case DEVICE_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: - processor.processRpcResponsesFromEdge(ctx, (FromDeviceRpcResponseActorMsg) msg); + processor.processRpcResponsesFromEdge((FromDeviceRpcResponseActorMsg) msg); break; case DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG: - processor.processServerSideRpcTimeout(ctx, (DeviceActorServerSideRpcTimeoutMsg) msg); + processor.processServerSideRpcTimeout((DeviceActorServerSideRpcTimeoutMsg) msg); break; case SESSION_TIMEOUT_MSG: processor.checkSessionsTimeout(); @@ -86,7 +86,7 @@ public class DeviceActor extends ContextAwareActor { processor.processEdgeUpdate((DeviceEdgeUpdateMsg) msg); break; case REMOVE_RPC_TO_DEVICE_ACTOR_MSG: - processor.processRemoveRpc(ctx, (RemoveRpcActorMsg) msg); + processor.processRemoveRpc((RemoveRpcActorMsg) msg); break; default: return false; diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 477e161ae1..0ce0ae7884 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -83,7 +83,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionInfoProt import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseStatusMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto; import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; @@ -204,7 +203,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso if (systemContext.isEdgesEnabled() && edgeId != null) { log.debug("[{}][{}] device is related to edge: [{}]. Saving RPC request: [{}][{}] to edge queue", tenantId, deviceId, edgeId.getId(), rpcId, requestId); try { - saveRpcRequestToEdgeQueue(request, rpcRequest.getRequestId()).get(); + saveRpcRequestToEdgeQueue(request, requestId).get(); sent = true; } catch (InterruptedException | ExecutionException e) { log.error("[{}][{}][{}] Failed to save RPC request to edge queue {}", tenantId, deviceId, edgeId.getId(), request, e); @@ -242,10 +241,6 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } } - private UUID getRpcIdFromRequest(ToDeviceRpcRequestMsg request) { - return new UUID(request.getRequestIdMSB(), request.getRequestIdLSB()); - } - private boolean isSendNewRpcAvailable() { return !rpcSequential || toDeviceRpcPendingMap.values().stream().filter(md -> !md.isDelivered()).findAny().isEmpty(); } @@ -276,7 +271,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso .build(); } - void processRpcResponsesFromEdge(TbActorCtx context, FromDeviceRpcResponseActorMsg responseMsg) { + void processRpcResponsesFromEdge(FromDeviceRpcResponseActorMsg responseMsg) { log.debug("[{}] Processing RPC command response from edge session", deviceId); ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); boolean success = requestMd != null; @@ -287,12 +282,12 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } } - void processRemoveRpc(TbActorCtx context, RemoveRpcActorMsg msg) { + void processRemoveRpc(RemoveRpcActorMsg msg) { UUID requestId = msg.getRequestId(); log.debug("[{}][{}] Received remove RPC request ...", deviceId, requestId); Map.Entry entry = null; for (Map.Entry e : toDeviceRpcPendingMap.entrySet()) { - if (e.getValue().getMsg().getMsg().getId().equals(msg.getRequestId())) { + if (e.getValue().getMsg().getMsg().getId().equals(requestId)) { entry = e; break; } @@ -307,7 +302,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso if (firstRpc.isPresent() && key.equals(firstRpc.get().getKey())) { toDeviceRpcPendingMap.remove(key); log.debug("[{}][{}][{}] Removed pending RPC! Going to send next pending request ...", deviceId, requestId, key); - sendNextPendingRequest(context); + sendNextPendingRequest(); } else { toDeviceRpcPendingMap.remove(key); } @@ -316,49 +311,52 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } private void registerPendingRpcRequest(TbActorCtx context, ToDeviceRpcRequestActorMsg msg, boolean sent, ToDeviceRpcRequestMsg rpcRequest, long timeout) { - log.debug("[{}][{}][{}] Registering pending RPC request...", deviceId, getRpcIdFromRequest(rpcRequest), rpcRequest.getRequestId()); - toDeviceRpcPendingMap.put(rpcRequest.getRequestId(), new ToDeviceRpcRequestMetadata(msg, sent)); - DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(rpcRequest.getRequestId(), timeout); + int requestId = rpcRequest.getRequestId(); + UUID rpcId = new UUID(rpcRequest.getRequestIdMSB(), rpcRequest.getRequestIdLSB()); + log.debug("[{}][{}][{}] Registering pending RPC request...", deviceId, rpcId, requestId); + toDeviceRpcPendingMap.put(requestId, new ToDeviceRpcRequestMetadata(msg, sent)); + DeviceActorServerSideRpcTimeoutMsg timeoutMsg = new DeviceActorServerSideRpcTimeoutMsg(requestId, timeout); scheduleMsgWithDelay(context, timeoutMsg, timeoutMsg.getTimeout()); } - void processServerSideRpcTimeout(TbActorCtx context, DeviceActorServerSideRpcTimeoutMsg msg) { + void processServerSideRpcTimeout(DeviceActorServerSideRpcTimeoutMsg msg) { Integer requestId = msg.getId(); ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(requestId); if (requestMd != null) { - UUID rpcId = requestMd.getMsg().getMsg().getId(); + ToDeviceRpcRequest toDeviceRpcRequest = requestMd.getMsg().getMsg(); + UUID rpcId = toDeviceRpcRequest.getId(); log.debug("[{}][{}][{}] RPC request timeout detected!", deviceId, rpcId, requestId); - if (requestMd.getMsg().getMsg().isPersisted()) { + if (toDeviceRpcRequest.isPersisted()) { systemContext.getTbRpcService().save(tenantId, new RpcId(rpcId), RpcStatus.EXPIRED, null); } systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(rpcId, null, requestMd.isSent() ? RpcError.TIMEOUT : RpcError.NO_ACTIVE_CONNECTION)); if (!requestMd.isDelivered()) { log.debug("[{}][{}][{}] Pending RPC timeout detected! Going to send next pending request ...", deviceId, rpcId, requestId); - sendNextPendingRequest(context); + sendNextPendingRequest(); } } } - private void sendPendingRequests(TbActorCtx context, UUID sessionId, String nodeId) { + private void sendPendingRequests(UUID sessionId, String nodeId) { SessionType sessionType = getSessionType(sessionId); if (!toDeviceRpcPendingMap.isEmpty()) { - log.debug("[{}][{}] Pushing {} pending RPC messages to new async session!", deviceId, sessionId, toDeviceRpcPendingMap.size()); + log.debug("[{}] Pushing {} pending RPC messages to session: [{}]", deviceId, sessionId, toDeviceRpcPendingMap.size()); if (sessionType == SessionType.SYNC) { log.debug("[{}] Cleanup sync RPC session [{}]", deviceId, sessionId); rpcSubscriptions.remove(sessionId); } } else { - log.debug("[{}] No pending RPC messages for new async session [{}]", deviceId, sessionId); + log.debug("[{}] No pending RPC messages for session: [{}]", deviceId, sessionId); } Set sentOneWayIds = new HashSet<>(); if (rpcSequential) { - getFirstRpc().ifPresent(processPendingRpc(context, sessionId, nodeId, sentOneWayIds)); + getFirstRpc().ifPresent(processPendingRpc(sessionId, nodeId, sentOneWayIds)); } else if (sessionType == SessionType.ASYNC) { - toDeviceRpcPendingMap.entrySet().forEach(processPendingRpc(context, sessionId, nodeId, sentOneWayIds)); + toDeviceRpcPendingMap.entrySet().forEach(processPendingRpc(sessionId, nodeId, sentOneWayIds)); } else { - toDeviceRpcPendingMap.entrySet().stream().findFirst().ifPresent(processPendingRpc(context, sessionId, nodeId, sentOneWayIds)); + toDeviceRpcPendingMap.entrySet().stream().findFirst().ifPresent(processPendingRpc(sessionId, nodeId, sentOneWayIds)); } sentOneWayIds.stream().filter(id -> !toDeviceRpcPendingMap.get(id).getMsg().getMsg().isPersisted()).forEach(toDeviceRpcPendingMap::remove); @@ -368,37 +366,38 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso return toDeviceRpcPendingMap.entrySet().stream().filter(e -> !e.getValue().isDelivered()).findFirst(); } - private void sendNextPendingRequest(TbActorCtx context) { + private void sendNextPendingRequest() { if (rpcSequential) { - rpcSubscriptions.forEach((id, s) -> sendPendingRequests(context, id, s.getNodeId())); + rpcSubscriptions.forEach((id, s) -> sendPendingRequests(id, s.getNodeId())); } } - private Consumer> processPendingRpc(TbActorCtx context, UUID sessionId, String nodeId, Set sentOneWayIds) { + private Consumer> processPendingRpc(UUID sessionId, String nodeId, Set sentOneWayIds) { return entry -> { ToDeviceRpcRequest request = entry.getValue().getMsg().getMsg(); ToDeviceRpcRequestBody body = request.getBody(); Integer requestId = entry.getKey(); + UUID rpcId = request.getId(); if (request.isOneway() && !rpcSequential) { sentOneWayIds.add(requestId); - systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(request.getId(), null, null)); + systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(rpcId, null, null)); } ToDeviceRpcRequestMsg rpcRequest = ToDeviceRpcRequestMsg.newBuilder() .setRequestId(requestId) .setMethodName(body.getMethod()) .setParams(body.getParams()) .setExpirationTime(request.getExpirationTime()) - .setRequestIdMSB(request.getId().getMostSignificantBits()) - .setRequestIdLSB(request.getId().getLeastSignificantBits()) + .setRequestIdMSB(rpcId.getMostSignificantBits()) + .setRequestIdLSB(rpcId.getLeastSignificantBits()) .setOneway(request.isOneway()) .setPersisted(request.isPersisted()) .build(); - log.debug("[{}][{}][{}][{}] Send pending RPC request to transport ...", deviceId, sessionId, getRpcIdFromRequest(rpcRequest), requestId); + log.debug("[{}][{}][{}][{}] Send pending RPC request to transport ...", deviceId, sessionId, rpcId, requestId); sendToTransport(rpcRequest, sessionId, nodeId); }; } - void process(TbActorCtx context, TransportToDeviceActorMsgWrapper wrapper) { + void process(TransportToDeviceActorMsgWrapper wrapper) { TransportToDeviceActorMsg msg = wrapper.getMsg(); TbCallback callback = wrapper.getCallback(); var sessionInfo = msg.getSessionInfo(); @@ -407,36 +406,36 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso processSessionStateMsgs(sessionInfo, msg.getSessionEvent()); } if (msg.hasSubscribeToAttributes()) { - processSubscriptionCommands(context, sessionInfo, msg.getSubscribeToAttributes()); + processSubscriptionCommands(sessionInfo, msg.getSubscribeToAttributes()); } if (msg.hasSubscribeToRPC()) { - processSubscriptionCommands(context, sessionInfo, msg.getSubscribeToRPC()); + processSubscriptionCommands(sessionInfo, msg.getSubscribeToRPC()); } if (msg.hasSendPendingRPC()) { - sendPendingRequests(context, getSessionId(sessionInfo), sessionInfo.getNodeId()); + sendPendingRequests(getSessionId(sessionInfo), sessionInfo.getNodeId()); } if (msg.hasGetAttributes()) { - handleGetAttributesRequest(context, sessionInfo, msg.getGetAttributes()); + handleGetAttributesRequest(sessionInfo, msg.getGetAttributes()); } if (msg.hasToDeviceRPCCallResponse()) { - processRpcResponses(context, sessionInfo, msg.getToDeviceRPCCallResponse()); + processRpcResponses(sessionInfo, msg.getToDeviceRPCCallResponse()); } if (msg.hasSubscriptionInfo()) { - handleSessionActivity(context, sessionInfo, msg.getSubscriptionInfo()); + handleSessionActivity(sessionInfo, msg.getSubscriptionInfo()); } if (msg.hasClaimDevice()) { - handleClaimDeviceMsg(context, sessionInfo, msg.getClaimDevice()); + handleClaimDeviceMsg(msg.getClaimDevice()); } if (msg.hasRpcResponseStatusMsg()) { - processRpcResponseStatus(context, sessionInfo, msg.getRpcResponseStatusMsg()); + processRpcResponseStatus(sessionInfo, msg.getRpcResponseStatusMsg()); } if (msg.hasUplinkNotificationMsg()) { - processUplinkNotificationMsg(context, sessionInfo, msg.getUplinkNotificationMsg()); + processUplinkNotificationMsg(sessionInfo, msg.getUplinkNotificationMsg()); } callback.onSuccess(); } - private void processUplinkNotificationMsg(TbActorCtx context, SessionInfoProto sessionInfo, TransportProtos.UplinkNotificationMsg uplinkNotificationMsg) { + private void processUplinkNotificationMsg(SessionInfoProto sessionInfo, TransportProtos.UplinkNotificationMsg uplinkNotificationMsg) { String nodeId = sessionInfo.getNodeId(); sessions.entrySet().stream() .filter(kv -> kv.getValue().getSessionInfo().getNodeId().equals(nodeId) && (kv.getValue().isSubscribedToAttributes() || kv.getValue().isSubscribedToRPC())) @@ -450,7 +449,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso }); } - private void handleClaimDeviceMsg(TbActorCtx context, SessionInfoProto sessionInfo, ClaimDeviceMsg msg) { + private void handleClaimDeviceMsg(ClaimDeviceMsg msg) { DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); systemContext.getClaimDevicesService().registerClaimingInfo(tenantId, deviceId, msg.getSecretKey(), msg.getDurationMs()); } @@ -463,7 +462,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso systemContext.getDeviceStateService().onDeviceDisconnect(tenantId, deviceId); } - private void handleGetAttributesRequest(TbActorCtx context, SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { + private void handleGetAttributesRequest(SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { int requestId = request.getRequestId(); if (request.getOnlyShared()) { Futures.addCallback(findAllAttributesByScope(DataConstants.SHARED_SCOPE), new FutureCallback<>() { @@ -547,7 +546,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso return sessions.containsKey(sessionId) ? SessionType.ASYNC : SessionType.SYNC; } - void processAttributesUpdate(TbActorCtx context, DeviceAttributesEventNotificationMsg msg) { + void processAttributesUpdate(DeviceAttributesEventNotificationMsg msg) { if (attributeSubscriptions.size() > 0) { boolean hasNotificationData = false; AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder(); @@ -584,10 +583,11 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } } - private void processRpcResponses(TbActorCtx context, SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg responseMsg) { + private void processRpcResponses(SessionInfoProto sessionInfo, ToDeviceRpcResponseMsg responseMsg) { UUID sessionId = getSessionId(sessionInfo); log.debug("[{}][{}] Processing RPC command response: {}", deviceId, sessionId, responseMsg); - ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(responseMsg.getRequestId()); + int requestId = responseMsg.getRequestId(); + ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(requestId); boolean success = requestMd != null; if (success) { ToDeviceRpcRequest toDeviceRequestMsg = requestMd.getMsg().getMsg(); @@ -610,16 +610,16 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } finally { if (!delivered) { String errorResponse = hasError ? "error" : ""; - log.debug("[{}][{}][{}] Received {} response for undelivered RPC! Going to send next pending request ...", deviceId, sessionId, responseMsg.getRequestId(), errorResponse); - sendNextPendingRequest(context); + log.debug("[{}][{}][{}] Received {} response for undelivered RPC! Going to send next pending request ...", deviceId, sessionId, requestId, errorResponse); + sendNextPendingRequest(); } } } else { - log.debug("[{}][{}][{}] RPC command response is stale!", deviceId, sessionId, responseMsg.getRequestId()); + log.debug("[{}][{}][{}] RPC command response is stale!", deviceId, sessionId, requestId); } } - private void processRpcResponseStatus(TbActorCtx context, SessionInfoProto sessionInfo, ToDeviceRpcResponseStatusMsg responseMsg) { + private void processRpcResponseStatus(SessionInfoProto sessionInfo, ToDeviceRpcResponseStatusMsg responseMsg) { UUID rpcId = new UUID(responseMsg.getRequestIdMSB(), responseMsg.getRequestIdLSB()); RpcStatus status = RpcStatus.valueOf(responseMsg.getStatus()); UUID sessionId = getSessionId(sessionInfo); @@ -655,17 +655,17 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } if (status != RpcStatus.SENT) { log.debug("[{}][{}][{}][{}] RPC was {}! Going to send next pending request ...", deviceId, sessionId, rpcId, requestId, status.name().toLowerCase()); - sendNextPendingRequest(context); + sendNextPendingRequest(); } } else { log.warn("[{}][{}][{}][{}] RPC has already been removed from pending map.", deviceId, sessionId, rpcId, requestId); } } - private void processSubscriptionCommands(TbActorCtx context, SessionInfoProto sessionInfo, SubscribeToAttributeUpdatesMsg subscribeCmd) { + private void processSubscriptionCommands(SessionInfoProto sessionInfo, SubscribeToAttributeUpdatesMsg subscribeCmd) { UUID sessionId = getSessionId(sessionInfo); if (subscribeCmd.getUnsubscribe()) { - log.debug("[{}] Canceling attributes subscription for session [{}]", deviceId, sessionId); + log.debug("[{}] Canceling attributes subscription for session: [{}]", deviceId, sessionId); attributeSubscriptions.remove(sessionId); } else { SessionInfoMetaData sessionMD = sessions.get(sessionId); @@ -673,7 +673,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso sessionMD = new SessionInfoMetaData(new SessionInfo(subscribeCmd.getSessionType(), sessionInfo.getNodeId())); } sessionMD.setSubscribedToAttributes(true); - log.debug("[{}] Registering attributes subscription for session [{}]", deviceId, sessionId); + log.debug("[{}] Registering attributes subscription for session: [{}]", deviceId, sessionId); attributeSubscriptions.put(sessionId, sessionMD.getSessionInfo()); dumpSessions(); } @@ -683,7 +683,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso return new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()); } - private void processSubscriptionCommands(TbActorCtx context, SessionInfoProto sessionInfo, SubscribeToRPCMsg subscribeCmd) { + private void processSubscriptionCommands(SessionInfoProto sessionInfo, SubscribeToRPCMsg subscribeCmd) { UUID sessionId = getSessionId(sessionInfo); if (subscribeCmd.getUnsubscribe()) { log.debug("[{}] Canceling RPC subscription for session: [{}]", deviceId, sessionId); @@ -696,7 +696,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso sessionMD.setSubscribedToRPC(true); rpcSubscriptions.put(sessionId, sessionMD.getSessionInfo()); log.debug("[{}] Registered RPC subscription for session: [{}] Going to check for pending requests ...", deviceId, sessionId); - sendPendingRequests(context, sessionId, sessionInfo.getNodeId()); + sendPendingRequests(sessionId, sessionInfo.getNodeId()); dumpSessions(); } } @@ -706,10 +706,10 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso Objects.requireNonNull(sessionId); if (msg.getEvent() == SessionEvent.OPEN) { if (sessions.containsKey(sessionId)) { - log.debug("[{}] Received duplicate session open event [{}]", deviceId, sessionId); + log.debug("[{}][{}] Received duplicate session open event.", deviceId, sessionId); return; } - log.debug("[{}] Processing new session [{}]. Current sessions size {}", deviceId, sessionId, sessions.size()); + log.debug("[{}] Processing new session: [{}] Current sessions size: {}", deviceId, sessionId, sessions.size()); sessions.put(sessionId, new SessionInfoMetaData(new SessionInfo(SessionType.ASYNC, sessionInfo.getNodeId()))); if (sessions.size() == 1) { @@ -718,7 +718,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso systemContext.getDeviceStateService().onDeviceActivity(tenantId, deviceId, System.currentTimeMillis()); dumpSessions(); } else if (msg.getEvent() == SessionEvent.CLOSED) { - log.debug("[{}] Canceling subscriptions for closed session [{}]", deviceId, sessionId); + log.debug("[{}][{}] Canceling subscriptions for closed session.", deviceId, sessionId); sessions.remove(sessionId); attributeSubscriptions.remove(sessionId); rpcSubscriptions.remove(sessionId); @@ -729,7 +729,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } } - private void handleSessionActivity(TbActorCtx context, SessionInfoProto sessionInfoProto, SubscriptionInfoProto subscriptionInfo) { + private void handleSessionActivity(SessionInfoProto sessionInfoProto, SubscriptionInfoProto subscriptionInfo) { UUID sessionId = getSessionId(sessionInfoProto); Objects.requireNonNull(sessionId); @@ -766,7 +766,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } private void notifyTransportAboutClosedSessionMaxSessionsLimit(UUID sessionId, SessionInfoMetaData sessionMd) { - log.debug("remove eldest session (max concurrent sessions limit reached per device) sessionId [{}] sessionMd [{}]", sessionId, sessionMd); + log.debug("remove eldest session (max concurrent sessions limit reached per device) sessionId: [{}] sessionMd: [{}]", sessionId, sessionMd); notifyTransportAboutClosedSession(sessionId, sessionMd, "max concurrent sessions limit reached per device!"); } @@ -830,14 +830,6 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso systemContext.getTbCoreToTransportService().process(nodeId, msg); } - private void sendToTransport(ToServerRpcResponseMsg rpcMsg, UUID sessionId, String nodeId) { - ToTransportMsg msg = ToTransportMsg.newBuilder() - .setSessionIdMSB(sessionId.getMostSignificantBits()) - .setSessionIdLSB(sessionId.getLeastSignificantBits()) - .setToServerResponse(rpcMsg).build(); - systemContext.getTbCoreToTransportService().process(nodeId, msg); - } - private ListenableFuture saveRpcRequestToEdgeQueue(ToDeviceRpcRequest msg, Integer requestId) { ObjectNode body = JacksonUtil.newObjectNode(); body.put("requestId", requestId); From cc3e5681a89a5dd134e77cc8eaf9aa33170dd847 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 7 Jun 2023 16:28:10 +0300 Subject: [PATCH 144/207] UI: Added clearing cache resources when we change user --- .../app/core/services/resources.service.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ui-ngx/src/app/core/services/resources.service.ts b/ui-ngx/src/app/core/services/resources.service.ts index 5dc20ddd46..55cda1660b 100644 --- a/ui-ngx/src/app/core/services/resources.service.ts +++ b/ui-ngx/src/app/core/services/resources.service.ts @@ -30,6 +30,9 @@ import { IModulesMap } from '@modules/common/modules-map.models'; import { TbResourceId } from '@shared/models/id/tb-resource-id'; import { isObject } from '@core/utils'; import { AuthService } from '@core/auth/auth.service'; +import { select, Store } from '@ngrx/store'; +import { selectIsAuthenticated } from '@core/auth/auth.selectors'; +import { AppState } from '@core/core.state'; declare const System; @@ -50,9 +53,12 @@ export class ResourcesService { private anchor = this.document.getElementsByTagName('head')[0] || this.document.getElementsByTagName('body')[0]; constructor(@Inject(DOCUMENT) private readonly document: any, + protected store: Store, private compiler: Compiler, private http: HttpClient, - private injector: Injector) {} + private injector: Injector) { + this.store.pipe(select(selectIsAuthenticated)).subscribe(() => this.clearCache()); + } public loadResource(url: string): Observable { if (this.loadedResources[url]) { @@ -270,4 +276,20 @@ export class ResourcesService { }; } } + + private deleteFromSystemJS(keys: string[]) { + keys.forEach(item => { + if (System.has(item)) { + System.delete(item); + } + }); + } + + private clearCache() { + this.deleteFromSystemJS(Object.keys(this.loadedModules)); + this.loadedModules = {}; + + this.deleteFromSystemJS(Object.keys(this.loadedModulesAndFactories)); + this.loadedModulesAndFactories = {}; + } } From 01065ec0c586d0d42d7bc5630ec3200d263a04dd Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 8 Jun 2023 10:32:26 +0300 Subject: [PATCH 145/207] UI: Fixed clear cache in SystemJs load resources --- .../app/core/services/resources.service.ts | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/ui-ngx/src/app/core/services/resources.service.ts b/ui-ngx/src/app/core/services/resources.service.ts index 55cda1660b..70084153e8 100644 --- a/ui-ngx/src/app/core/services/resources.service.ts +++ b/ui-ngx/src/app/core/services/resources.service.ts @@ -33,6 +33,7 @@ import { AuthService } from '@core/auth/auth.service'; import { select, Store } from '@ngrx/store'; import { selectIsAuthenticated } from '@core/auth/auth.selectors'; import { AppState } from '@core/core.state'; +import { tap } from 'rxjs/operators'; declare const System; @@ -57,7 +58,7 @@ export class ResourcesService { private compiler: Compiler, private http: HttpClient, private injector: Injector) { - this.store.pipe(select(selectIsAuthenticated)).subscribe(() => this.clearCache()); + this.store.pipe(select(selectIsAuthenticated)).subscribe(() => this.clearModulesCache()); } public loadResource(url: string): Observable { @@ -71,9 +72,9 @@ export class ResourcesService { fileType = match[1]; } if (!fileType) { - return throwError(new Error(`Unable to detect file type from url: ${url}`)); + return throwError(() => new Error(`Unable to detect file type from url: ${url}`)); } else if (fileType !== 'css' && fileType !== 'js') { - return throwError(new Error(`Unsupported file type: ${fileType}`)); + return throwError(() => new Error(`Unsupported file type: ${fileType}`)); } return this.loadResourceByType(fileType, url); } @@ -97,7 +98,8 @@ export class ResourcesService { for (const m of modules) { tasks.push(this.compiler.compileModuleAndAllComponentsAsync(m)); } - forkJoin(tasks).subscribe((compiled) => { + forkJoin(tasks).subscribe({ + next: (compiled) => { try { const componentFactories: ComponentFactory[] = []; for (const c of compiled) { @@ -112,26 +114,32 @@ export class ResourcesService { this.loadedModulesAndFactories[url].complete(); } catch (e) { this.loadedModulesAndFactories[url].error(new Error(`Unable to init module from url: ${url}`)); - delete this.loadedModulesAndFactories[url]; } }, - (e) => { + error: (e) => { this.loadedModulesAndFactories[url].error(new Error(`Unable to compile module from url: ${url}`)); - delete this.loadedModulesAndFactories[url]; - }); + } + }); } else { this.loadedModulesAndFactories[url].error(new Error(`Module '${url}' doesn't have default export!`)); - delete this.loadedModulesAndFactories[url]; } }, (e) => { this.loadedModulesAndFactories[url].error(new Error(`Unable to load module from url: ${url}`)); - delete this.loadedModulesAndFactories[url]; } ); } ); - return subject.asObservable(); + return subject.asObservable().pipe( + tap({ + next: () => System.delete(url), + error: () => { + delete this.loadedModulesAndFactories[url]; + System.delete(url); + }, + complete: () => System.delete(url) + }) + ); } public loadModules(resourceId: string | TbResourceId, modulesMap: IModulesMap): Observable[]> { @@ -168,31 +176,35 @@ export class ResourcesService { this.loadedModules[url].complete(); } catch (e) { this.loadedModules[url].error(new Error(`Unable to init module from url: ${url}`)); - delete this.loadedModules[url]; } }, (e) => { this.loadedModules[url].error(new Error(`Unable to compile module from url: ${url}`)); - delete this.loadedModules[url]; }); } else { this.loadedModules[url].error(new Error(`Module '${url}' doesn't have default export or not NgModule!`)); - delete this.loadedModules[url]; } } catch (e) { this.loadedModules[url].error(new Error(`Unable to load module from url: ${url}`)); - delete this.loadedModules[url]; } }, (e) => { this.loadedModules[url].error(new Error(`Unable to load module from url: ${url}`)); - delete this.loadedModules[url]; console.error(`Unable to load module from url: ${url}`, e); } ); } ); - return subject.asObservable(); + return subject.asObservable().pipe( + tap({ + next: () => System.delete(url), + error: () => { + delete this.loadedModulesAndFactories[url]; + System.delete(url); + }, + complete: () => System.delete(url) + }) + ); } private extractNgModules(module: any, modules: Type[] = []): Type[] { @@ -277,19 +289,8 @@ export class ResourcesService { } } - private deleteFromSystemJS(keys: string[]) { - keys.forEach(item => { - if (System.has(item)) { - System.delete(item); - } - }); - } - - private clearCache() { - this.deleteFromSystemJS(Object.keys(this.loadedModules)); + private clearModulesCache() { this.loadedModules = {}; - - this.deleteFromSystemJS(Object.keys(this.loadedModulesAndFactories)); this.loadedModulesAndFactories = {}; } } From a48416e442f59071ea12829b3c5d830139a1c83a Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 8 Jun 2023 10:43:21 +0300 Subject: [PATCH 146/207] UI: Fixed process error in resource library component --- .../resource/resource-autocomplete.component.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.ts b/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.ts index 6debdb49d9..8489fe0640 100644 --- a/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.ts +++ b/ui-ngx/src/app/shared/components/resource/resource-autocomplete.component.ts @@ -130,9 +130,15 @@ export class ResourceAutocompleteComponent implements ControlValueAccessor, OnIn if (isDefinedAndNotNull(value)) { this.searchText = ''; if (isObject(value) && typeof value !== 'string' && (value as TbResourceId).id) { - this.resourceService.getResourceInfo(value.id, {ignoreLoading: true, ignoreErrors: true}).subscribe(resource => { - this.modelValue = resource.id; - this.resourceFormGroup.get('resource').patchValue(resource, {emitEvent: false}); + this.resourceService.getResourceInfo(value.id, {ignoreLoading: true, ignoreErrors: true}).subscribe({ + next: resource => { + this.modelValue = resource.id; + this.resourceFormGroup.get('resource').patchValue(resource, {emitEvent: false}); + }, + error: () => { + this.modelValue = ''; + this.resourceFormGroup.get('resource').patchValue(''); + } }); } else { this.modelValue = value; From a0e6128f364ab28cd30834a18fc5072bb6d14af4 Mon Sep 17 00:00:00 2001 From: kalytka Date: Thu, 8 Jun 2023 11:26:00 +0300 Subject: [PATCH 147/207] Add ToggleHeaderComponent to the module-map --- ui-ngx/src/app/modules/common/modules-map.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui-ngx/src/app/modules/common/modules-map.ts b/ui-ngx/src/app/modules/common/modules-map.ts index 5cc9a49d42..83b5a25a70 100644 --- a/ui-ngx/src/app/modules/common/modules-map.ts +++ b/ui-ngx/src/app/modules/common/modules-map.ts @@ -177,6 +177,7 @@ import * as CopyButtonComponent from '@shared/components/button/copy-button.comp import * as TogglePasswordComponent from '@shared/components/button/toggle-password.component'; import * as ProtobufContentComponent from '@shared/components/protobuf-content.component'; import * as SlackConversationAutocompleteComponent from '@shared/components/slack-conversation-autocomplete.component'; +import * as ToggleHeaderComponent from '@shared/components/toggle-header.component'; import * as AddEntityDialogComponent from '@home/components/entity/add-entity-dialog.component'; import * as EntitiesTableComponent from '@home/components/entity/entities-table.component'; @@ -474,6 +475,7 @@ class ModulesMap implements IModulesMap { '@shared/components/button/toggle-password.component': TogglePasswordComponent, '@shared/components/protobuf-content.component': ProtobufContentComponent, '@shared/components/slack-conversation-autocomplete.component': SlackConversationAutocompleteComponent, + '@shared/components/toggle-header.component': ToggleHeaderComponent, '@home/components/entity/add-entity-dialog.component': AddEntityDialogComponent, '@home/components/entity/entities-table.component': EntitiesTableComponent, From 9a37fe7853b77098eccb1f313b6cc13f83e0f933 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 8 Jun 2023 12:27:42 +0300 Subject: [PATCH 148/207] UI: Math function rule node fixed validation --- .../resources/public/static/rulenode/rulenode-core-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js index 58f4b4ecdc..584309bd9f 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js +++ b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js @@ -1 +1 @@ -System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/platform-browser","@angular/material/select","@angular/material/core","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/icon","@angular/material/chips","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/material/tooltip","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","rxjs","@angular/material/expansion","@home/components/public-api","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@angular/material/radio","@angular/material/slide-toggle","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component"],(function(e){"use strict";var t,r,n,a,o,i,l,s,m,u,p,d,c,f,g,y,x,b,h,C,F,v,L,k,I,T,N,q,S,M,A,G,E,D,V,P,R,w,O,H,K,B,U,z,j,_,$,J,Q,Y,W,X,Z,ee,te,re,ne,ae,oe,ie,le,se,me,ue,pe,de,ce,fe,ge,ye,xe,be,he,Ce,Fe,ve,Le,ke,Ie,Te,Ne,qe,Se,Me,Ae,Ge,Ee,De,Ve,Pe,Re,we,Oe,He,Ke;return{setters:[function(e){t=e,r=e.Component,n=e.Pipe,a=e.ViewChild,o=e.forwardRef,i=e.Input,l=e.NgModule},function(e){s=e.RuleNodeConfigurationComponent,m=e.AttributeScope,u=e.telemetryTypeTranslations,p=e.ServiceType,d=e.ScriptLanguage,c=e.AlarmSeverity,f=e.alarmSeverityTranslations,g=e.EntitySearchDirection,y=e.entitySearchDirectionTranslations,x=e.EntityType,b=e.PageComponent,h=e.MessageType,C=e.messageTypeNames,F=e,v=e.SharedModule,L=e.AggregationType,k=e.aggregationTranslations,I=e.NotificationType,T=e.SlackChanelType,N=e.SlackChanelTypesTranslateMap,q=e.alarmStatusTranslations,S=e.AlarmStatus},function(e){M=e},function(e){A=e,G=e.Validators,E=e.NgControl,D=e.NG_VALUE_ACCESSOR,V=e.NG_VALIDATORS,P=e.UntypedFormControl},function(e){R=e,w=e.CommonModule},function(e){O=e},function(e){H=e},function(e){K=e},function(e){B=e},function(e){U=e},function(e){z=e},function(e){j=e},function(e){_=e},function(e){$=e},function(e){J=e.getCurrentAuthState,Q=e,Y=e.isDefinedAndNotNull,W=e.isObject,X=e.isUndefinedOrNull,Z=e.isNotEmptyStr},function(e){ee=e},function(e){te=e},function(e){re=e},function(e){ne=e.ENTER,ae=e.COMMA,oe=e.SEMICOLON},function(e){ie=e},function(e){le=e},function(e){se=e},function(e){me=e},function(e){ue=e.coerceBooleanProperty},function(e){pe=e},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e.tap,xe=e.map,be=e.mergeMap,he=e.takeUntil,Ce=e.startWith,Fe=e.share},function(e){ve=e},function(e){Le=e},function(e){ke=e.of,Ie=e.Subject},function(e){Te=e},function(e){Ne=e.HomeComponentsModule},function(e){qe=e},function(e){Se=e},function(e){Me=e},function(e){Ae=e},function(e){Ge=e},function(e){Ee=e},function(e){De=e},function(e){Ve=e},function(e){Pe=e},function(e){Re=e},function(e){we=e},function(e){Oe=e},function(e){He=e},function(e){Ke=e}],execute:function(){class Be extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",Be),Be.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Be,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Be.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Be,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Be,decorators:[{type:r,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ue{constructor(e){this.sanitizer=e}transform(e){return this.sanitizer.bypassSecurityTrustHtml(e)}}e("SafeHtmlPipe",Ue),Ue.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ue,deps:[{token:z.DomSanitizer}],target:t.ɵɵFactoryTarget.Pipe}),Ue.ɵpipe=t.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Ue,name:"safeHtml"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ue,decorators:[{type:n,args:[{name:"safeHtml"}]}],ctorParameters:function(){return[{type:z.DomSanitizer}]}});class ze extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[G.required,G.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[G.required,G.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ze),ze.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ze,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ze.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ze,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ze,decorators:[{type:r,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class je extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===m.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",je),je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:je,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:je,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:je,decorators:[{type:r,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class _e extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[G.required]]})}}e("CheckPointConfigComponent",_e),_e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_e,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:_e,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_e,decorators:[{type:r,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class $e extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[G.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===d.JS?[G.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===d.TBEL?[G.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.clearAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=e===d.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",n=this.clearAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.clearAlarmConfigForm.get(t).setValue(e)}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",$e),$e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$e,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),$e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:$e,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$e,decorators:[{type:r,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Je extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.alarmSeverities=Object.keys(c),this.alarmSeverityTranslationMap=f,this.separatorKeysCodes=[ne,ae,oe],this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,r=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([G.required]),this.createAlarmConfigForm.get("severity").setValidators([G.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let n=this.createAlarmConfigForm.get("scriptLang").value;n!==d.TBEL||this.tbelEnabled||(n=d.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(n,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const a=!1===t||!0===r;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(a&&n===d.JS?[G.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(a&&n===d.TBEL?[G.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.createAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=e===d.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",n=this.createAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.createAlarmConfigForm.get(t).setValue(e)}))}removeKey(e,t){const r=this.createAlarmConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.createAlarmConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",Je),Je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Je,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Je,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Je,decorators:[{type:r,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Qe extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[G.required]],entityType:[e?e.entityType:null,[G.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[G.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[G.required,G.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==x.DEVICE&&t!==x.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([G.required,G.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",Qe),Qe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qe,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Qe,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qe,decorators:[{type:r,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ye extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[G.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[G.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[G.required,G.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,r=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([G.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&r?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",Ye),Ye.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ye,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ye.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ye,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ye,decorators:[{type:r,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class We extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,G.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,G.required]})}}e("DeviceProfileConfigComponent",We),We.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:We,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),We.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:We,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:We,decorators:[{type:r,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Xe extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[G.required,G.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[G.required,G.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(){const e=this.generatorConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",n=this.generatorConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.generatorConfigForm.get(t).setValue(e)}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}var Ze;e("GeneratorConfigComponent",Xe),Xe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xe,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Xe,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xe,decorators:[{type:r,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(Ze||(Ze={}));const et=new Map([[Ze.CUSTOMER,"tb.rulenode.originator-customer"],[Ze.TENANT,"tb.rulenode.originator-tenant"],[Ze.RELATED,"tb.rulenode.originator-related"],[Ze.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[Ze.ENTITY,"tb.rulenode.originator-entity"]]);var tt;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(tt||(tt={}));const rt=new Map([[tt.CIRCLE,"tb.rulenode.perimeter-circle"],[tt.POLYGON,"tb.rulenode.perimeter-polygon"]]);var nt;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(nt||(nt={}));const at=new Map([[nt.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[nt.SECONDS,"tb.rulenode.time-unit-seconds"],[nt.MINUTES,"tb.rulenode.time-unit-minutes"],[nt.HOURS,"tb.rulenode.time-unit-hours"],[nt.DAYS,"tb.rulenode.time-unit-days"]]);var ot;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(ot||(ot={}));const it=new Map([[ot.METER,"tb.rulenode.range-unit-meter"],[ot.KILOMETER,"tb.rulenode.range-unit-kilometer"],[ot.FOOT,"tb.rulenode.range-unit-foot"],[ot.MILE,"tb.rulenode.range-unit-mile"],[ot.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var lt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(lt||(lt={}));const st=new Map([[lt.ID,"tb.rulenode.entity-details-id"],[lt.TITLE,"tb.rulenode.entity-details-title"],[lt.COUNTRY,"tb.rulenode.entity-details-country"],[lt.STATE,"tb.rulenode.entity-details-state"],[lt.CITY,"tb.rulenode.entity-details-city"],[lt.ZIP,"tb.rulenode.entity-details-zip"],[lt.ADDRESS,"tb.rulenode.entity-details-address"],[lt.ADDRESS2,"tb.rulenode.entity-details-address2"],[lt.PHONE,"tb.rulenode.entity-details-phone"],[lt.EMAIL,"tb.rulenode.entity-details-email"],[lt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var mt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(mt||(mt={}));const ut=new Map([[mt.FIRST,"tb.rulenode.first-message"],[mt.LAST,"tb.rulenode.last-message"],[mt.ALL,"tb.rulenode.all-messages"]]);var pt,dt;!function(e){e.ASC="ASC",e.DESC="DESC"}(pt||(pt={})),function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(dt||(dt={}));const ct=new Map([[dt.STANDARD,"tb.rulenode.sqs-queue-standard"],[dt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),ft=["anonymous","basic","cert.PEM"],gt=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),yt=["sas","cert.PEM"],xt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var bt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(bt||(bt={}));const ht=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Ct=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Ft;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Ft||(Ft={}));const vt=new Map([[Ft.CUSTOM,{value:Ft.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Ft.ADD,{value:Ft.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Ft.SUB,{value:Ft.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Ft.MULT,{value:Ft.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Ft.DIV,{value:Ft.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Ft.SIN,{value:Ft.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Ft.SINH,{value:Ft.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Ft.COS,{value:Ft.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Ft.COSH,{value:Ft.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Ft.TAN,{value:Ft.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Ft.TANH,{value:Ft.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Ft.ACOS,{value:Ft.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Ft.ASIN,{value:Ft.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Ft.ATAN,{value:Ft.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Ft.ATAN2,{value:Ft.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Ft.EXP,{value:Ft.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Ft.EXPM1,{value:Ft.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Ft.SQRT,{value:Ft.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Ft.CBRT,{value:Ft.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Ft.GET_EXP,{value:Ft.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Ft.HYPOT,{value:Ft.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Ft.LOG,{value:Ft.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Ft.LOG10,{value:Ft.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Ft.LOG1P,{value:Ft.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Ft.CEIL,{value:Ft.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Ft.FLOOR,{value:Ft.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Ft.FLOOR_DIV,{value:Ft.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Ft.FLOOR_MOD,{value:Ft.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Ft.ABS,{value:Ft.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Ft.MIN,{value:Ft.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Ft.MAX,{value:Ft.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Ft.POW,{value:Ft.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Ft.SIGNUM,{value:Ft.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Ft.RAD,{value:Ft.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Ft.DEG,{value:Ft.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Lt,kt;!function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Lt||(Lt={})),function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(kt||(kt={}));const It=new Map([[Lt.ATTRIBUTE,"tb.rulenode.attribute-type"],[Lt.TIME_SERIES,"tb.rulenode.time-series-type"],[Lt.CONSTANT,"tb.rulenode.constant-type"],[Lt.MESSAGE_BODY,"tb.rulenode.message-body-type"],[Lt.MESSAGE_METADATA,"tb.rulenode.message-metadata-type"]]),Tt=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var Nt,qt;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(Nt||(Nt={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(qt||(qt={}));const St=new Map([[Nt.SHARED_SCOPE,"tb.rulenode.shared-scope"],[Nt.SERVER_SCOPE,"tb.rulenode.server-scope"],[Nt.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class Mt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=tt,this.perimeterTypes=Object.keys(tt),this.perimeterTypeTranslationMap=rt,this.rangeUnits=Object.keys(ot),this.rangeUnitTranslationMap=it,this.timeUnits=Object.keys(nt),this.timeUnitsTranslationMap=at}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[G.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[G.required]],perimeterType:[e?e.perimeterType:null,[G.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[G.required,G.min(1),G.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[G.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[G.required,G.min(1),G.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[G.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,r=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([G.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||r!==tt.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([G.required,G.min(-90),G.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([G.required,G.min(-180),G.max(180)]),this.geoActionConfigForm.get("range").setValidators([G.required,G.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([G.required])),t||r!==tt.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([G.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",Mt),Mt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Mt,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mt,decorators:[{type:r,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class At extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.logConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",n=this.logConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.logConfigForm.get(t).setValue(e)}))}onValidate(){this.logConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",At),At.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:At,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),At.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:At,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:At,decorators:[{type:r,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Gt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[G.required,G.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[G.required]]})}}e("MsgCountConfigComponent",Gt),Gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Gt,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gt,decorators:[{type:r,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Et extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[G.required,G.min(1),G.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([G.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([G.required,G.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",Et),Et.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Et,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Et.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Et,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Et,decorators:[{type:r,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Dt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]]})}}e("PushToCloudConfigComponent",Dt),Dt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Dt,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dt,decorators:[{type:r,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Vt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]]})}}e("PushToEdgeConfigComponent",Vt),Vt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Vt,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vt,decorators:[{type:r,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Pt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",Pt),Pt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Pt,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pt,decorators:[{type:r,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Rt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[G.required,G.min(0)]]})}}e("RpcRequestConfigComponent",Rt),Rt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Rt,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rt,decorators:[{type:r,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class wt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(E),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const r of Object.keys(e))Object.prototype.hasOwnProperty.call(e,r)&&t.push(this.fb.group({key:[r,[G.required]],value:[e[r],[G.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[G.required]],value:["",[G.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",wt),wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wt,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:wt,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:D,useExisting:o((()=>wt)),multi:!0},{provide:V,useExisting:o((()=>wt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#0000008a;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:de.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ce.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wt,decorators:[{type:r,args:[{selector:"tb-kv-map-config",providers:[{provide:D,useExisting:o((()=>wt)),multi:!0},{provide:V,useExisting:o((()=>wt)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#0000008a;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class Ot extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[G.required,G.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[G.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",Ot),Ot.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ot,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ot.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ot,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ot,decorators:[{type:r,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ht extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[G.required,G.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Ht),Ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ht,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ht,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ht,decorators:[{type:r,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Kt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[G.required,G.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[G.required,G.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Kt),Kt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Kt,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kt,decorators:[{type:r,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Bt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]],keys:[e?e.keys:null,[G.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",Bt),Bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Bt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Bt,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Bt,decorators:[{type:r,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:a,args:["attributeChipList"]}]}});class Ut extends b{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup())}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=vt,this.ArgumentType=Lt,this.attributeScopeMap=St,this.argumentTypeResultMap=It,this.arguments=Object.values(Lt),this.attributeScope=Object.values(Nt),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.ngControl=this.injector.get(E),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.argumentsFormGroup=this.fb.group({}),this.argumentsFormGroup.addControl("arguments",this.fb.array([])),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray(),r=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,r),this.updateArgumentNames()}argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):this.argumentsFormGroup.enable({emitEvent:!1})}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()));const t=[];e&&e.forEach(((e,r)=>{t.push(this.createArgumentControl(e,r))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t)),this.setupArgumentsFormGroup(),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()})))}removeArgument(e){this.argumentsFormGroup.get("arguments").removeAt(e),this.updateArgumentNames()}addArgument(){const e=this.argumentsFormGroup.get("arguments"),t=this.createArgumentControl(null,e.length);e.push(t)}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Ft.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([G.minLength(this.minArgs),G.maxLength(this.maxArgs)]),this.argumentsFormGroup.get("arguments").value.length>this.maxArgs&&(this.argumentsFormGroup.get("arguments").controls.length=this.maxArgs);this.argumentsFormGroup.get("arguments").value.length{this.updateArgumentControlValidators(r),r.get("attributeScope").updateValueAndValidity({emitEvent:!0}),r.get("defaultValue").updateValueAndValidity({emitEvent:!0})}))),r}updateArgumentControlValidators(e){const t=e.get("type").value;t===Lt.ATTRIBUTE?e.get("attributeScope").enable():e.get("attributeScope").disable(),t&&t!==Lt.CONSTANT?e.get("defaultValue").enable():e.get("defaultValue").disable()}updateArgumentNames(){this.argumentsFormGroup.get("arguments").controls.forEach(((e,t)=>{e.get("name").setValue(Tt[t])}))}updateModel(){const e=this.argumentsFormGroup.get("arguments").value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Ut),Ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ut,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ut,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:D,useExisting:o((()=>Ut)),multi:!0},{provide:V,useExisting:o((()=>Ut)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"],dependencies:[{kind:"directive",type:R.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:de.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:fe.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:fe.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:ge.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:ge.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:ge.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ce.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ut,decorators:[{type:r,args:[{selector:"tb-arguments-map-config",providers:[{provide:D,useExisting:o((()=>Ut)),multi:!0},{provide:V,useExisting:o((()=>Ut)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class zt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.searchText="",this.dirty=!1,this.mathOperation=[...vt.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(ye((e=>{let t;t="string"==typeof e&&Ft[e]?Ft[e]:null,this.updateView(t)})),xe((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=vt.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",zt),zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zt,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:zt,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:D,useExisting:o((()=>zt)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zt,decorators:[{type:r,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:D,useExisting:o((()=>zt)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:a,args:["operationInput",{static:!0}]}]}});class jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Ft,this.ArgumentTypeResult=kt,this.argumentTypeResultMap=It,this.attributeScopeMap=St,this.argumentsResult=Object.values(kt),this.attributeScopeResult=Object.values(qt)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[G.required]],arguments:[e?e.arguments:null,[G.required]],customFunction:[e?e.customFunction:"",[G.required]],result:this.fb.group({type:[e?e.result.type:null,[G.required]],attributeScope:[e?e.result.attributeScope:null],key:[e?e.result.key:"",[G.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,r=this.mathFunctionConfigForm.get("result").get("type").value;t===Ft.CUSTOM?this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),r===kt.ATTRIBUTE?this.mathFunctionConfigForm.get("result").get("attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result").get("attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result").get("attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",jt),jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:jt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:jt,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:A.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ut,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:zt,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:jt,decorators:[{type:r,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class _t{constructor(e,t){this.store=e,this.fb=t,this.subscriptSizing="fixed",this.searchText="",this.dirty=!1,this.messageTypes=["POST_ATTRIBUTES_REQUEST","POST_TELEMETRY_REQUEST"],this.propagateChange=e=>{},this.messageTypeFormGroup=this.fb.group({messageType:[null,[G.required,G.maxLength(255)]]})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.outputMessageTypes=this.messageTypeFormGroup.get("messageType").valueChanges.pipe(ye((e=>{this.updateView(e)})),xe((e=>e||"")),be((e=>this.fetchMessageTypes(e))))}writeValue(e){this.searchText="",this.modelValue=e,this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1}),this.dirty=!0}onFocus(){this.dirty&&(this.messageTypeFormGroup.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0}),this.dirty=!1)}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}displayMessageTypeFn(e){return e||void 0}fetchMessageTypes(e,t=!1){return this.searchText=e,ke(this.messageTypes).pipe(xe((r=>r.filter((r=>t?!!e&&r===e:!e||r.toUpperCase().startsWith(e.toUpperCase()))))))}clear(){this.messageTypeFormGroup.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}}e("OutputMessageTypeAutocompleteComponent",_t),_t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_t,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:_t,selector:"tb-output-message-type-autocomplete",inputs:{autocompleteHint:"autocompleteHint",subscriptSizing:"subscriptSizing"},providers:[{provide:D,useExisting:o((()=>_t)),multi:!0}],viewQueries:[{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0,static:!0}],ngImport:t,template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_t,decorators:[{type:r,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:D,useExisting:o((()=>_t)),multi:!0}],template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{messageTypeInput:[{type:a,args:["messageTypeInput",{static:!0}]}],autocompleteHint:[{type:i}],subscriptSizing:[{type:i}]}});class $t extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.destroy$=new Ie,this.serviceType=p.TB_RULE_ENGINE,this.deduplicationStrategie=mt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=ut}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[Y(e?.interval)?e.interval:null,[G.required,G.min(1)]],strategy:[Y(e?.strategy)?e.strategy:null,[G.required]],outMsgType:[Y(e?.outMsgType)?e.outMsgType:null,[G.required]],queueName:[Y(e?.queueName)?e.queueName:null,[G.required]],maxPendingMsgs:[Y(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[G.required,G.min(1),G.max(1e3)]],maxRetries:[Y(e?.maxRetries)?e.maxRetries:null,[G.required,G.min(0),G.max(100)]]}),this.deduplicationConfigForm.get("strategy").valueChanges.pipe(he(this.destroy$)).subscribe((e=>{this.enableControl(e)}))}updateValidators(e){this.enableControl(this.deduplicationConfigForm.get("strategy").value)}validatorTriggers(){return["strategy"]}enableControl(e){e===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("DeduplicationConfigComponent",$t),$t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$t,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:$t,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:_t,selector:"tb-output-message-type-autocomplete",inputs:["autocompleteHint","subscriptSizing"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$t,decorators:[{type:r,args:[{selector:"tb-action-node-msg-deduplication-config",template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Jt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[G.required]],maxLevel:[null,[]],relationType:[null],deviceTypes:[null,[G.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",Jt),Jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Jt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Jt,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:D,useExisting:o((()=>Jt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-type
\n \n \n
device.device-types
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:qe.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","disabled","entityType"]},{kind:"component",type:Se.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["required","disabled","subscriptSizing"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Jt,decorators:[{type:r,args:[{selector:"tb-device-relations-query-config",providers:[{provide:D,useExisting:o((()=>Jt)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-type
\n \n \n
device.device-types
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Qt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[G.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",Qt),Qt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Qt,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:D,useExisting:o((()=>Qt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Me.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qt,decorators:[{type:r,args:[{selector:"tb-relations-query-config",providers:[{provide:D,useExisting:o((()=>Qt)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Yt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.truncate=r,this.fb=n,this.placeholder="tb.rulenode.message-type",this.separatorKeysCodes=[ne,ae,oe],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(h))this.messageTypesList.push({name:C.get(h[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchMessageTypes(e))),Fe())}ngAfterViewInit(){}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return!!(e&&null!=e&&e.length>0)}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return ke(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t=null;const r=e.trim(),n=this.messageTypesList.find((e=>e.name===r));t=n?{name:n.name,value:n.value}:{name:r,value:r},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Yt),Yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Yt,deps:[{token:M.Store},{token:U.TranslateService},{token:F.TruncatePipe},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Yt,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:D,useExisting:o((()=>Yt)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) | async }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Yt,decorators:[{type:r,args:[{selector:"tb-message-types-config",providers:[{provide:D,useExisting:o((()=>Yt)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) | async }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:F.TruncatePipe},{type:A.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:a,args:["chipList",{static:!1}]}],matAutocomplete:[{type:a,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:a,args:["messageTypeInput",{static:!1}]}]}});class Wt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=ft,this.credentialsTypeTranslationsMap=gt,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[G.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const r=e[t];if(!r.firstChange&&r.currentValue!==r.previousValue&&r.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){Y(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([G.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[G.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(G.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return r=>{t||(t=[Object.keys(r.controls)]);return r?.controls&&t.some((t=>t.every((t=>!e(r.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",Wt),Wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Wt,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Wt,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:D,useExisting:o((()=>Wt)),multi:!0},{provide:V,useExisting:o((()=>Wt)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:R.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:R.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Te.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Wt,decorators:[{type:r,args:[{selector:"tb-credentials-config",providers:[{provide:D,useExisting:o((()=>Wt)),multi:!0},{provide:V,useExisting:o((()=>Wt)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});class Xt{}e("RulenodeCoreConfigCommonModule",Xt),Xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xt,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Xt.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Xt,declarations:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t],imports:[w,v,Ne],exports:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t]}),Xt.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xt,imports:[w,v,Ne]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xt,decorators:[{type:l,args:[{declarations:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t],imports:[w,v,Ne],exports:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t]}]}]});class Zt{}e("RuleNodeCoreConfigActionModule",Zt),Zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zt,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Zt.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Zt,declarations:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t],imports:[w,v,Ne,Xt],exports:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t]}),Zt.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zt,imports:[w,v,Ne,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zt,decorators:[{type:l,args:[{declarations:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t],imports:[w,v,Ne,Xt],exports:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t]}]}]});class er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e?e.inputValueKey:null,[G.required]],outputValueKey:[e?e.outputValueKey:null,[G.required]],useCache:[e?e.useCache:null,[]],addPeriodBetweenMsgs:[!!e&&e.addPeriodBetweenMsgs,[]],periodValueKey:[e?e.periodValueKey:null,[]],round:[e?e.round:null,[G.min(0),G.max(15)]],tellFailureIfDeltaIsNegative:[e?e.tellFailureIfDeltaIsNegative:null,[]]})}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([G.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:er,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:er,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:'
\n
\n \n tb.rulenode.input-value-key\n \n \n {{ \'tb.rulenode.input-value-key-required\' | translate }}\n \n \n \n tb.rulenode.output-value-key\n \n \n {{ \'tb.rulenode.output-value-key-required\' | translate }}\n \n \n \n tb.rulenode.round\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n
\n \n {{ \'tb.rulenode.use-cache\' | translate }}\n \n \n {{ \'tb.rulenode.tell-failure-if-delta-is-negative\' | translate }}\n \n \n {{ \'tb.rulenode.add-period-between-msgs\' | translate }}\n \n \n tb.rulenode.period-value-key\n \n \n {{ \'tb.rulenode.period-value-key-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:er,decorators:[{type:r,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:'
\n
\n \n tb.rulenode.input-value-key\n \n \n {{ \'tb.rulenode.input-value-key-required\' | translate }}\n \n \n \n tb.rulenode.output-value-key\n \n \n {{ \'tb.rulenode.output-value-key-required\' | translate }}\n \n \n \n tb.rulenode.round\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n
\n \n {{ \'tb.rulenode.use-cache\' | translate }}\n \n \n {{ \'tb.rulenode.tell-failure-if-delta-is-negative\' | translate }}\n \n \n {{ \'tb.rulenode.add-period-between-msgs\' | translate }}\n \n \n tb.rulenode.period-value-key\n \n \n {{ \'tb.rulenode.period-value-key-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.customerAttributesConfigForm}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("CustomerAttributesConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:tr,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e?e.deviceRelationsQuery:null,[G.required]],tellFailureIfAbsent:[!!e&&e.tellFailureIfAbsent,[]],fetchToData:[!!e&&e.fetchToData,[]],clientAttributeNames:[e?e.clientAttributeNames:null,[]],sharedAttributeNames:[e?e.sharedAttributeNames:null,[]],serverAttributeNames:[e?e.serverAttributeNames:null,[]],latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],getLatestValueWithTs:[!!e&&e.getLatestValueWithTs,[]]})}removeKey(e,t){const r=this.deviceAttributesConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.deviceAttributesConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deviceAttributesConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deviceAttributesConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}prepareInputConfig(e){return W(e)&&X(e?.fetchToData)&&(e.fetchToData=!1),e}}e("DeviceAttributesConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:rr,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Jt,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n \n \n \n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class nr extends s{constructor(e,t,r){super(e),this.store=e,this.translate=t,this.fb=r,this.entityDetailsTranslationsMap=st,this.entityDetailsList=[],this.searchText="",this.displayDetailsFn=this.displayDetails.bind(this);for(const e of Object.keys(lt))this.entityDetailsList.push(lt[e]);this.detailsFormControl=new P(""),this.filteredEntityDetails=this.detailsFormControl.valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchEntityDetails(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){return this.searchText="",this.detailsFormControl.patchValue("",{emitEvent:!0}),this.detailsList=e?e.detailsList:[],e}prepareOutputConfig(e){return e.detailsList=this.detailsList,e}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e?e.detailsList:null,[G.required]],addToMetadata:[!!e&&e.addToMetadata,[]]}),this.detailsList=e?e.detailsList:[]}displayDetails(e){return e?this.translate.instant(st.get(e)):void 0}fetchEntityDetails(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(this.entityDetailsList.filter((t=>this.translate.instant(st.get(lt[t])).toUpperCase().includes(e))))}return ke(this.entityDetailsList)}detailsFieldSelected(e){this.addDetailsField(e.option.value),this.clear("")}removeDetailsField(e){const t=this.detailsList.indexOf(e);t>=0&&(this.detailsList.splice(t,1),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}addDetailsField(e){this.detailsList||(this.detailsList=[]);-1===this.detailsList.indexOf(e)&&(this.detailsList.push(e),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}onEntityDetailsInputFocus(){this.detailsFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.detailsInput.nativeElement.value=e,this.detailsFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}}e("EntityDetailsConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nr,deps:[{token:M.Store},{token:U.TranslateService},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:nr,selector:"tb-enrichment-node-entity-details-config",viewQueries:[{propertyName:"detailsInput",first:!0,predicate:["detailsInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.entity-details\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-entity-details-matching\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n {{ \'tb.rulenode.add-to-metadata\' | translate }}\n \n
tb.rulenode.add-to-metadata-hint
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n tb.rulenode.entity-details\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-entity-details-matching\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n {{ \'tb.rulenode.add-to-metadata\' | translate }}\n \n
tb.rulenode.add-to-metadata-hint
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:A.UntypedFormBuilder}]},propDecorators:{detailsInput:[{type:a,args:["detailsInput",{static:!1}]}]}});class ar extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe],this.aggregationTypes=L,this.aggregations=Object.keys(L),this.aggregationTypesTranslations=k,this.fetchMode=mt,this.fetchModes=Object.keys(mt),this.samplingOrders=Object.keys(pt),this.timeUnits=Object.values(nt),this.timeUnitsTranslationMap=at}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],aggregation:[e?e.aggregation:null,[G.required]],fetchMode:[e?e.fetchMode:null,[G.required]],orderBy:[e?e.orderBy:null,[]],limit:[e?e.limit:null,[]],useMetadataIntervalPatterns:[!!e&&e.useMetadataIntervalPatterns,[]],startInterval:[e?e.startInterval:null,[]],startIntervalTimeUnit:[e?e.startIntervalTimeUnit:null,[]],endInterval:[e?e.endInterval:null,[]],endIntervalTimeUnit:[e?e.endIntervalTimeUnit:null,[]],startIntervalPattern:[e?e.startIntervalPattern:null,[]],endIntervalPattern:[e?e.endIntervalPattern:null,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,r=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===mt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([G.required,G.min(2),G.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),r?(this.getTelemetryFromDatabaseConfigForm.get("startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([G.required])):(this.getTelemetryFromDatabaseConfigForm.get("startInterval").setValidators([G.required,G.min(1),G.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("endInterval").setValidators([G.required,G.min(1),G.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const r=this.getTelemetryFromDatabaseConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}}e("GetTelemetryFromDatabaseConfigComponent",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ar,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ar,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeseries-key\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.fetch-mode\n \n \n {{ mode }}\n \n \n tb.rulenode.fetch-mode-hint\n \n
\n \n aggregation.function\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n \n tb.rulenode.order-by\n \n \n {{ order }}\n \n \n tb.rulenode.order-by-hint\n \n \n tb.rulenode.limit\n \n tb.rulenode.limit-hint\n \n
\n \n {{ \'tb.rulenode.use-metadata-interval-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-interval-patterns-hint
\n
\n
\n \n tb.rulenode.start-interval\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.start-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.end-interval\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.end-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n \n tb.rulenode.start-interval-pattern\n \n \n {{ \'tb.rulenode.start-interval-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.end-interval-pattern\n \n \n {{ \'tb.rulenode.end-interval-pattern-required\' | translate }}\n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ar,decorators:[{type:r,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n tb.rulenode.timeseries-key\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.fetch-mode\n \n \n {{ mode }}\n \n \n tb.rulenode.fetch-mode-hint\n \n
\n \n aggregation.function\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n \n tb.rulenode.order-by\n \n \n {{ order }}\n \n \n tb.rulenode.order-by-hint\n \n \n tb.rulenode.limit\n \n tb.rulenode.limit-hint\n \n
\n \n {{ \'tb.rulenode.use-metadata-interval-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-interval-patterns-hint
\n
\n
\n \n tb.rulenode.start-interval\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.start-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.end-interval\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.end-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n \n tb.rulenode.start-interval-pattern\n \n \n {{ \'tb.rulenode.start-interval-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.end-interval-pattern\n \n \n {{ \'tb.rulenode.end-interval-pattern-required\' | translate }}\n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[!!e&&e.tellFailureIfAbsent,[]],fetchToData:[!!Y(e?.fetchToData)&&e.fetchToData,[]],clientAttributeNames:[e?e.clientAttributeNames:null,[]],sharedAttributeNames:[e?e.sharedAttributeNames:null,[]],serverAttributeNames:[e?e.serverAttributeNames:null,[]],latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],getLatestValueWithTs:[!!e&&e.getLatestValueWithTs,[]]})}removeKey(e,t){const r=this.originatorAttributesConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.originatorAttributesConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.originatorAttributesConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.originatorAttributesConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}prepareInputConfig(e){return W(e)&&X(e?.fetchToData)&&(e.fetchToData=!1),e}}e("OriginatorAttributesConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:or,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:or,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:or,decorators:[{type:r,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.originatorFieldsConfigForm}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({fieldsMapping:[e?e.fieldsMapping:null,[G.required]],ignoreNullStrings:[e?e.ignoreNullStrings:null]})}}e("OriginatorFieldsConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ir,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ir,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n {{ "tb.rulenode.ignore-null-strings" | translate }}\n
{{ "tb.rulenode.ignore-null-strings-hint" | translate }}
\n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ir,decorators:[{type:r,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n {{ "tb.rulenode.ignore-null-strings" | translate }}\n
{{ "tb.rulenode.ignore-null-strings-hint" | translate }}
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class lr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.relatedAttributesConfigForm}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e?e.relationsQuery:null,[G.required]],telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("RelatedAttributesConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:lr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:lr,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"component",type:Qt,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:lr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n \n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class sr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.tenantAttributesConfigForm}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("TenantAttributesConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:sr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:sr,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:sr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class mr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchToMetadata:[e?e.fetchToMetadata:null,[]]})}}e("FetchDeviceCredentialsConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:mr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:mr,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n {{ \'tb.rulenode.fetch-credentials-to-metadata\' | translate }}\n
\n',dependencies:[{kind:"component",type:De.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:mr,decorators:[{type:r,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n {{ \'tb.rulenode.fetch-credentials-to-metadata\' | translate }}\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class ur{}e("RulenodeCoreConfigEnrichmentModule",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:ur,declarations:[tr,nr,rr,or,ir,ar,lr,sr,er,mr],imports:[w,v,Xt],exports:[tr,nr,rr,or,ir,ar,lr,sr,er,mr]}),ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,decorators:[{type:l,args:[{declarations:[tr,nr,rr,or,ir,ar,lr,sr,er,mr],imports:[w,v,Xt],exports:[tr,nr,rr,or,ir,ar,lr,sr,er,mr]}]}]});class pr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=yt,this.azureIotHubCredentialsTypeTranslationsMap=xt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[G.required,G.min(1),G.max(200)]],clientId:[e?e.clientId:null,[G.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[G.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),r=t.get("type").value;switch(e&&t.reset({type:r},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),r){case"sas":t.get("sasKey").setValidators([G.required]);break;case"cert.PEM":t.get("privateKey").setValidators([G.required]),t.get("privateKeyFileName").setValidators([G.required]),t.get("cert").setValidators([G.required]),t.get("certFileName").setValidators([G.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:pr,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:R.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:R.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Te.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:A.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pr,decorators:[{type:r,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class dr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=ht,this.ToByteStandartCharsetTypeTranslationMap=Ct}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[G.required]],retries:[e?e.retries:null,[G.min(0)]],batchSize:[e?e.batchSize:null,[G.min(0)]],linger:[e?e.linger:null,[G.min(0)]],bufferMemory:[e?e.bufferMemory:null,[G.min(0)]],acks:[e?e.acks:null,[G.required]],keySerializer:[e?e.keySerializer:null,[G.required]],valueSerializer:[e?e.valueSerializer:null,[G.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([G.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:dr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:dr,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:dr,decorators:[{type:r,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class cr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[]}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[G.required,G.min(1),G.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&Z(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]}),this.subscriptions.push(this.mqttConfigForm.get("clientId").valueChanges.subscribe((e=>{Z(e)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1})})))}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}}e("MqttConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:cr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:cr,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Wt,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:cr,decorators:[{type:r,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class fr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=I,this.entityType=x}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[G.required]],targets:[e?e.targets:[],[G.required]]})}}e("NotificationConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:fr,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:fr,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:Ve.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Pe.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","disabled","notificationTypes"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:fr,decorators:[{type:r,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]}});class gr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[G.required]],topicName:[e?e.topicName:null,[G.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[G.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[G.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:gr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:gr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:gr,decorators:[{type:r,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class yr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[G.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[G.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:yr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:yr,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:yr,decorators:[{type:r,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class xr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(bt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[G.required]],requestMethod:[e?e.requestMethod:null,[G.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],trimDoubleQuotes:[!!e&&e.trimDoubleQuotes,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[G.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,r=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,n=this.restApiCallConfigForm.get("enableProxy").value,a=this.restApiCallConfigForm.get("useSystemProxyProperties").value;n&&!a?(this.restApiCallConfigForm.get("proxyHost").setValidators(n?[G.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(n?[G.required,G.min(1),G.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([G.min(0)])),r?this.restApiCallConfigForm.get("maxQueueSize").setValidators([G.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:xr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:xr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"component",type:Wt,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:xr,decorators:[{type:r,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class br extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,r=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([G.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([G.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([G.required,G.min(1),G.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([G.required,G.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(r?[G.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(r?[G.required,G.min(1),G.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:br,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:br,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Re.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:br,decorators:[{type:r,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class hr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[G.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[G.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([G.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:hr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:hr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:we.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:hr,decorators:[{type:r,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Cr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(T),this.slackChanelTypesTranslateMap=N}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[G.required]],conversationType:[e?e.conversationType:null,[G.required]],conversation:[e?e.conversation:null,[G.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([G.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Cr,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Cr,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Oe.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Cr,decorators:[{type:r,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]}});class Fr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[G.required]],accessKeyId:[e?e.accessKeyId:null,[G.required]],secretAccessKey:[e?e.secretAccessKey:null,[G.required]],region:[e?e.region:null,[G.required]]})}}e("SnsConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Fr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Fr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Fr,decorators:[{type:r,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class vr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=dt,this.sqsQueueTypes=Object.keys(dt),this.sqsQueueTypeTranslationsMap=ct}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[G.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[G.required]],delaySeconds:[e?e.delaySeconds:null,[G.min(0),G.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[G.required]],secretAccessKey:[e?e.secretAccessKey:null,[G.required]],region:[e?e.region:null,[G.required]]})}}e("SqsConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:vr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:vr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:vr,decorators:[{type:r,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Lr{}e("RulenodeCoreConfigExternalModule",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Lr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Lr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Lr,declarations:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr],imports:[w,v,Ne,Xt],exports:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr]}),Lr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Lr,imports:[w,v,Ne,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Lr,decorators:[{type:l,args:[{declarations:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr],imports:[w,v,Ne,Xt],exports:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr]}]}]});class kr extends s{constructor(e,t,r){super(e),this.store=e,this.translate=t,this.fb=r,this.alarmStatusTranslationsMap=q,this.alarmStatusList=[],this.searchText="",this.displayStatusFn=this.displayStatus.bind(this);for(const e of Object.keys(S))this.alarmStatusList.push(S[e]);this.statusFormControl=new P(""),this.filteredAlarmStatus=this.statusFormControl.valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchAlarmStatus(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return this.searchText="",this.statusFormControl.patchValue("",{emitEvent:!0}),e}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e?e.alarmStatusList:null,[G.required]]})}displayStatus(e){return e?this.translate.instant(q.get(e)):void 0}fetchAlarmStatus(e){const t=this.getAlarmStatusList();if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(t.filter((t=>this.translate.instant(q.get(S[t])).toUpperCase().includes(e))))}return ke(t)}alarmStatusSelected(e){this.addAlarmStatus(e.option.value),this.clear("")}removeAlarmStatus(e){const t=this.alarmStatusConfigForm.get("alarmStatusList").value;if(t){const r=t.indexOf(e);r>=0&&(t.splice(r,1),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}}addAlarmStatus(e){let t=this.alarmStatusConfigForm.get("alarmStatusList").value;t||(t=[]);-1===t.indexOf(e)&&(t.push(e),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}getAlarmStatusList(){return this.alarmStatusList.filter((e=>-1===this.alarmStatusConfigForm.get("alarmStatusList").value.indexOf(e)))}onAlarmStatusInputFocus(){this.statusFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.alarmStatusInput.nativeElement.value=e,this.statusFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.alarmStatusInput.nativeElement.blur(),this.alarmStatusInput.nativeElement.focus()}),0)}}e("CheckAlarmStatusComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:kr,deps:[{token:M.Store},{token:U.TranslateService},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:kr,selector:"tb-filter-node-check-alarm-status-config",viewQueries:[{propertyName:"alarmStatusInput",first:!0,predicate:["alarmStatusInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:kr,decorators:[{type:r,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:A.UntypedFormBuilder}]},propDecorators:{alarmStatusInput:[{type:a,args:["alarmStatusInput",{static:!1}]}]}});class Ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.checkMessageConfigForm}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e?e.messageNames:null,[]],metadataNames:[e?e.metadataNames:null,[]],checkAllKeys:[!!e&&e.checkAllKeys,[]]})}validateConfig(){const e=this.checkMessageConfigForm.get("messageNames").value,t=this.checkMessageConfigForm.get("metadataNames").value;return e.length>0||t.length>0}removeMessageName(e){const t=this.checkMessageConfigForm.get("messageNames").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.checkMessageConfigForm.get("messageNames").setValue(t,{emitEvent:!0}))}removeMetadataName(e){const t=this.checkMessageConfigForm.get("metadataNames").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.checkMessageConfigForm.get("metadataNames").setValue(t,{emitEvent:!0}))}addMessageName(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.checkMessageConfigForm.get("messageNames").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.checkMessageConfigForm.get("messageNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}addMetadataName(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.checkMessageConfigForm.get("metadataNames").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.checkMessageConfigForm.get("metadataNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CheckMessageConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ir,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ir,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ir,decorators:[{type:r,args:[{selector:"tb-filter-node-check-message-config",template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.keys(g),this.entitySearchDirectionTranslationsMap=y}configForm(){return this.checkRelationConfigForm}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[!!e&&e.checkForSingleEntity,[]],direction:[e?e.direction:null,[]],entityType:[e?e.entityType:null,e&&e.checkForSingleEntity?[G.required]:[]],entityId:[e?e.entityId:null,e&&e.checkForSingleEntity?[G.required]:[]],relationType:[e?e.relationType:null,[G.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[G.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[G.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Tr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Tr,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Se.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["required","disabled","subscriptSizing"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Tr,decorators:[{type:r,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Nr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=tt,this.perimeterTypes=Object.keys(tt),this.perimeterTypeTranslationMap=rt,this.rangeUnits=Object.keys(ot),this.rangeUnitTranslationMap=it}configForm(){return this.geoFilterConfigForm}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[G.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[G.required]],perimeterType:[e?e.perimeterType:null,[G.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,r=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([G.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||r!==tt.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([])):(this.geoFilterConfigForm.get("centerLatitude").setValidators([G.required,G.min(-90),G.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([G.required,G.min(-180),G.max(180)]),this.geoFilterConfigForm.get("range").setValidators([G.required,G.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([G.required])),t||r!==tt.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([G.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",Nr),Nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Nr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Nr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Nr,decorators:[{type:r,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class qr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e?e.messageTypes:null,[G.required]]})}}e("MessageTypeConfigComponent",qr),qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:qr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),qr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:qr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Yt,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:qr,decorators:[{type:r,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Sr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.TENANT,x.CUSTOMER,x.USER,x.DASHBOARD,x.RULE_CHAIN,x.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e?e.originatorTypes:null,[G.required]]})}}e("OriginatorTypeConfigComponent",Sr),Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Sr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Sr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n
\n',dependencies:[{kind:"component",type:Ke.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","disabled","subscriptSizing","allowedEntityTypes","ignoreAuthorityFilter"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Sr,decorators:[{type:r,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Mr extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",n=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Mr),Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mr,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Mr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mr,decorators:[{type:r,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Ar extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.switchConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",n=this.switchConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.switchConfigForm.get(t).setValue(e)}))}onValidate(){this.switchConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Ar),Ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ar,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ar,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ar,decorators:[{type:r,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Gr{}e("RuleNodeCoreConfigFilterModule",Gr),Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Gr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Gr,declarations:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr],imports:[w,v,Xt],exports:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr]}),Gr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gr,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gr,decorators:[{type:l,args:[{declarations:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr],imports:[w,v,Xt],exports:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr]}]}]});class Er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=Ze,this.originatorSources=Object.keys(Ze),this.originatorSourceTranslationMap=et,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.USER,x.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[G.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===Ze.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([G.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===Ze.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([G.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Er),Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Er,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Er,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Er,decorators:[{type:r,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Dr extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[G.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",n=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Dr),Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dr,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Dr,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dr,decorators:[{type:r,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Vr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",value:"false"},{name:"tb.mail-body-type.html",value:"true"},{name:"tb.mail-body-type.dynamic",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[G.required]],toTemplate:[e?e.toTemplate:null,[G.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[G.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null],bodyTemplate:[e?e.bodyTemplate:null,[G.required]]}),this.toEmailConfigForm.get("mailBodyType").valueChanges.pipe(Ce([e?.subjectTemplate])).subscribe((e=>{"dynamic"===e?(this.toEmailConfigForm.get("isHtmlTemplate").patchValue("",{emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").setValidators(G.required)):this.toEmailConfigForm.get("isHtmlTemplate").clearValidators(),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity()}))}}e("ToEmailConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Vr,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vr,decorators:[{type:r,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Pr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],keys:[e?e.keys:null,[G.required]]})}configForm(){return this.copyKeysConfigForm}removeKey(e){const t=this.copyKeysConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.copyKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.copyKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.copyKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CopyKeysConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Pr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pr,decorators:[{type:r,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[G.required]]})}}e("RenameKeysConfigComponent",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Rr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rr,decorators:[{type:r,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class wr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[G.required]]})}}e("NodeJsonPathConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:wr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n",dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wr,decorators:[{type:r,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n"}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],keys:[e?e.keys:null,[G.required]]})}configForm(){return this.deleteKeysConfigForm}removeKey(e){const t=this.deleteKeysConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.deleteKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.deleteKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.deleteKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteKeysConfigComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Or,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Or,decorators:[{type:r,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Hr{}e("RulenodeCoreConfigTransformModule",Hr),Hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Hr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Hr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Hr,declarations:[Er,Dr,Vr,Pr,Rr,wr,Or],imports:[w,v,Xt],exports:[Er,Dr,Vr,Pr,Rr,wr,Or]}),Hr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Hr,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Hr,decorators:[{type:l,args:[{declarations:[Er,Dr,Vr,Pr,Rr,wr,Or],imports:[w,v,Xt],exports:[Er,Dr,Vr,Pr,Rr,wr,Or]}]}]});class Kr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=x}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[G.required]]})}}e("RuleChainInputComponent",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Kr,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:He.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kr,decorators:[{type:r,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Br extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Br,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Br,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Br,decorators:[{type:r,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ur{}e("RuleNodeCoreConfigFlowModule",Ur),Ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Ur,declarations:[Kr,Br],imports:[w,v,Xt],exports:[Kr,Br]}),Ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ur,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ur,decorators:[{type:l,args:[{declarations:[Kr,Br],imports:[w,v,Xt],exports:[Kr,Br]}]}]});class zr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{"create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","output-message-type":"Output message type","output-message-type-required":"Output message type is required","output-message-type-max-length":"Output message type should be less than 256","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","start-interval":"Start Interval","end-interval":"End Interval","start-interval-time-unit":"Start Interval Time Unit","end-interval-time-unit":"End Interval Time Unit","fetch-mode":"Fetch mode","fetch-mode-hint":"If selected fetch mode 'ALL' you able to choose telemetry sampling order.","order-by":"Order by","order-by-hint":"Select to choose telemetry sampling order.",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. In case you want to fetch a single entry, select fetch mode 'FIRST' or 'LAST'.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Time value should be in a range from 1 to 2147483647.","start-interval-value-required":"Start interval value is required.","end-interval-value-required":"End interval value is required.",filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attribute keys","shared-attributes":"Shared attribute keys","server-attributes":"Server attribute keys","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Notify device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-hint":"If the message arrives from the device, we will push it back to the device by default.","notify-device-delete-hint":"Send notification about deleted attributes to device.","latest-timeseries":"Latest time-series data keys","timeseries-key":"Time-series key","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Hint: use regular expression to copy keys by pattern",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.","first-message":"First Message","last-message":"Last Message","all-messages":"All Messages","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",metadata:"Metadata","key-name":"Key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern","fetch-into":"Fetch into","attr-mapping":"Attributes mapping","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-attribute":"Target attribute","target-attribute-required":"Target attribute is required.","attr-mapping-required":"At least one attribute mapping should be specified.","fields-mapping":"Fields mapping","fields-mapping-required":"At least one field mapping should be specified.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","body-template":"Body Template","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","trim-double-quotes":"Message without quotes","trim-double-quotes-hint":"If selected, request body message payload will be sent without double quotes, i.e. msg = message body","read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Hint: Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Hint: Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Hint: Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-interval-patterns":"Use interval patterns","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval-pattern":"Start interval pattern","end-interval-pattern":"End interval pattern","start-interval-pattern-required":"Start interval pattern is required","end-interval-pattern-required":"End interval pattern is required","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"entity-details":"Select entity details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","add-to-metadata":"Add selected details to message metadata","add-to-metadata-hint":"If selected, adds the selected details keys to the message metadata instead of message data.","entity-details-list-empty":"No entity details selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-key-name":"Latitude key name","longitude-key-name":"Longitude key name","latitude-key-name-required":"Latitude key name is required.","longitude-key-name-required":"Longitude key name is required.","fetch-perimeter-info-from-message-metadata":"Fetch perimeter information from message metadata","perimeter-key-name":"Perimeter key name","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Please, use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.",round:"Decimals","round-range":"Decimals should be in a range from 0 to 15.","use-cache":"Use cache for latest value","tell-failure-if-delta-is-negative":"Tell Failure if delta is negative","add-period-between-msgs":"Add period between messages","period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"alarm-severity-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body to substitute "Source" and "Target" key names',"shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time series","message-body-type":"Message body","message-metadata-type":"Message metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-type-field-input":"Type","argument-type-field-input-required":"Argument type is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Hint: use 0 to convert result to integer","add-to-body-field-input":"Add to message body","add-to-metadata-field-input":"Add to message metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Hint: specify a mathematical expression to evaluate. For example, transform Fahrenheit to Celsius using (x - 32) / 1.8)","retained-message":"Retained","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required"},"key-val":{key:"Key",value:"Value","remove-entry":"Remove entry","add-entry":"Add entry","unique-key-value-pair-error":"'{{valText}}' must be different from the current '{{keyText}}'"},"mail-body-type":{"plain-text":"Plain Text",html:"HTML",dynamic:"Dynamic"}}},!0)}(e)}}e("RuleNodeCoreConfigModule",zr),zr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zr,deps:[{token:U.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),zr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:zr,declarations:[Be],imports:[w,v],exports:[Zt,Gr,ur,Lr,Hr,Ur,Be]}),zr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zr,imports:[w,v,Zt,Gr,ur,Lr,Hr,Ur]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zr,decorators:[{type:l,args:[{declarations:[Be],imports:[w,v],exports:[Zt,Gr,ur,Lr,Hr,Ur,Be]}]}],ctorParameters:function(){return[{type:U.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map +System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/platform-browser","@angular/material/select","@angular/material/core","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/icon","@angular/material/chips","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/material/tooltip","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","rxjs","@angular/material/expansion","@home/components/public-api","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@angular/material/radio","@angular/material/slide-toggle","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component"],(function(e){"use strict";var t,r,n,a,o,i,l,s,m,u,p,d,c,f,g,y,x,b,h,C,F,v,L,k,I,T,N,q,S,M,A,G,E,D,V,P,R,w,O,H,K,B,U,z,j,_,$,J,Q,Y,W,X,Z,ee,te,re,ne,ae,oe,ie,le,se,me,ue,pe,de,ce,fe,ge,ye,xe,be,he,Ce,Fe,ve,Le,ke,Ie,Te,Ne,qe,Se,Me,Ae,Ge,Ee,De,Ve,Pe,Re,we,Oe,He,Ke;return{setters:[function(e){t=e,r=e.Component,n=e.Pipe,a=e.ViewChild,o=e.forwardRef,i=e.Input,l=e.NgModule},function(e){s=e.RuleNodeConfigurationComponent,m=e.AttributeScope,u=e.telemetryTypeTranslations,p=e.ServiceType,d=e.ScriptLanguage,c=e.AlarmSeverity,f=e.alarmSeverityTranslations,g=e.EntitySearchDirection,y=e.entitySearchDirectionTranslations,x=e.EntityType,b=e.PageComponent,h=e.MessageType,C=e.messageTypeNames,F=e,v=e.SharedModule,L=e.AggregationType,k=e.aggregationTranslations,I=e.NotificationType,T=e.SlackChanelType,N=e.SlackChanelTypesTranslateMap,q=e.alarmStatusTranslations,S=e.AlarmStatus},function(e){M=e},function(e){A=e,G=e.Validators,E=e.NgControl,D=e.NG_VALUE_ACCESSOR,V=e.NG_VALIDATORS,P=e.UntypedFormControl},function(e){R=e,w=e.CommonModule},function(e){O=e},function(e){H=e},function(e){K=e},function(e){B=e},function(e){U=e},function(e){z=e},function(e){j=e},function(e){_=e},function(e){$=e},function(e){J=e.getCurrentAuthState,Q=e,Y=e.isDefinedAndNotNull,W=e.isObject,X=e.isUndefinedOrNull,Z=e.isNotEmptyStr},function(e){ee=e},function(e){te=e},function(e){re=e},function(e){ne=e.ENTER,ae=e.COMMA,oe=e.SEMICOLON},function(e){ie=e},function(e){le=e},function(e){se=e},function(e){me=e},function(e){ue=e.coerceBooleanProperty},function(e){pe=e},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e.tap,xe=e.map,be=e.mergeMap,he=e.takeUntil,Ce=e.startWith,Fe=e.share},function(e){ve=e},function(e){Le=e},function(e){ke=e.of,Ie=e.Subject},function(e){Te=e},function(e){Ne=e.HomeComponentsModule},function(e){qe=e},function(e){Se=e},function(e){Me=e},function(e){Ae=e},function(e){Ge=e},function(e){Ee=e},function(e){De=e},function(e){Ve=e},function(e){Pe=e},function(e){Re=e},function(e){we=e},function(e){Oe=e},function(e){He=e},function(e){Ke=e}],execute:function(){class Be extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",Be),Be.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Be,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Be.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Be,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Be,decorators:[{type:r,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ue{constructor(e){this.sanitizer=e}transform(e){return this.sanitizer.bypassSecurityTrustHtml(e)}}e("SafeHtmlPipe",Ue),Ue.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ue,deps:[{token:z.DomSanitizer}],target:t.ɵɵFactoryTarget.Pipe}),Ue.ɵpipe=t.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Ue,name:"safeHtml"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ue,decorators:[{type:n,args:[{name:"safeHtml"}]}],ctorParameters:function(){return[{type:z.DomSanitizer}]}});class ze extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[G.required,G.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[G.required,G.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ze),ze.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ze,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ze.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ze,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ze,decorators:[{type:r,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class je extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===m.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",je),je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:je,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:je,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:je,decorators:[{type:r,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class _e extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[G.required]]})}}e("CheckPointConfigComponent",_e),_e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_e,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:_e,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_e,decorators:[{type:r,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class $e extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[G.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===d.JS?[G.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===d.TBEL?[G.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.clearAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=e===d.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",n=this.clearAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.clearAlarmConfigForm.get(t).setValue(e)}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",$e),$e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$e,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),$e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:$e,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$e,decorators:[{type:r,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Je extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.alarmSeverities=Object.keys(c),this.alarmSeverityTranslationMap=f,this.separatorKeysCodes=[ne,ae,oe],this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,r=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([G.required]),this.createAlarmConfigForm.get("severity").setValidators([G.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let n=this.createAlarmConfigForm.get("scriptLang").value;n!==d.TBEL||this.tbelEnabled||(n=d.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(n,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const a=!1===t||!0===r;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(a&&n===d.JS?[G.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(a&&n===d.TBEL?[G.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.createAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=e===d.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",n=this.createAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.createAlarmConfigForm.get(t).setValue(e)}))}removeKey(e,t){const r=this.createAlarmConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.createAlarmConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",Je),Je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Je,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Je,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Je,decorators:[{type:r,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Qe extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[G.required]],entityType:[e?e.entityType:null,[G.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[G.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[G.required,G.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==x.DEVICE&&t!==x.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([G.required,G.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",Qe),Qe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qe,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Qe,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qe,decorators:[{type:r,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ye extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[G.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[G.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[G.required,G.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,r=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([G.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&r?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",Ye),Ye.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ye,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ye.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ye,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ye,decorators:[{type:r,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class We extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,G.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,G.required]})}}e("DeviceProfileConfigComponent",We),We.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:We,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),We.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:We,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:We,decorators:[{type:r,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Xe extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[G.required,G.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[G.required,G.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(){const e=this.generatorConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",n=this.generatorConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.generatorConfigForm.get(t).setValue(e)}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}var Ze;e("GeneratorConfigComponent",Xe),Xe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xe,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Xe,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xe,decorators:[{type:r,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(Ze||(Ze={}));const et=new Map([[Ze.CUSTOMER,"tb.rulenode.originator-customer"],[Ze.TENANT,"tb.rulenode.originator-tenant"],[Ze.RELATED,"tb.rulenode.originator-related"],[Ze.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[Ze.ENTITY,"tb.rulenode.originator-entity"]]);var tt;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(tt||(tt={}));const rt=new Map([[tt.CIRCLE,"tb.rulenode.perimeter-circle"],[tt.POLYGON,"tb.rulenode.perimeter-polygon"]]);var nt;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(nt||(nt={}));const at=new Map([[nt.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[nt.SECONDS,"tb.rulenode.time-unit-seconds"],[nt.MINUTES,"tb.rulenode.time-unit-minutes"],[nt.HOURS,"tb.rulenode.time-unit-hours"],[nt.DAYS,"tb.rulenode.time-unit-days"]]);var ot;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(ot||(ot={}));const it=new Map([[ot.METER,"tb.rulenode.range-unit-meter"],[ot.KILOMETER,"tb.rulenode.range-unit-kilometer"],[ot.FOOT,"tb.rulenode.range-unit-foot"],[ot.MILE,"tb.rulenode.range-unit-mile"],[ot.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var lt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(lt||(lt={}));const st=new Map([[lt.ID,"tb.rulenode.entity-details-id"],[lt.TITLE,"tb.rulenode.entity-details-title"],[lt.COUNTRY,"tb.rulenode.entity-details-country"],[lt.STATE,"tb.rulenode.entity-details-state"],[lt.CITY,"tb.rulenode.entity-details-city"],[lt.ZIP,"tb.rulenode.entity-details-zip"],[lt.ADDRESS,"tb.rulenode.entity-details-address"],[lt.ADDRESS2,"tb.rulenode.entity-details-address2"],[lt.PHONE,"tb.rulenode.entity-details-phone"],[lt.EMAIL,"tb.rulenode.entity-details-email"],[lt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var mt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(mt||(mt={}));const ut=new Map([[mt.FIRST,"tb.rulenode.first-message"],[mt.LAST,"tb.rulenode.last-message"],[mt.ALL,"tb.rulenode.all-messages"]]);var pt,dt;!function(e){e.ASC="ASC",e.DESC="DESC"}(pt||(pt={})),function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(dt||(dt={}));const ct=new Map([[dt.STANDARD,"tb.rulenode.sqs-queue-standard"],[dt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),ft=["anonymous","basic","cert.PEM"],gt=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),yt=["sas","cert.PEM"],xt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var bt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(bt||(bt={}));const ht=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Ct=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Ft;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Ft||(Ft={}));const vt=new Map([[Ft.CUSTOM,{value:Ft.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Ft.ADD,{value:Ft.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Ft.SUB,{value:Ft.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Ft.MULT,{value:Ft.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Ft.DIV,{value:Ft.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Ft.SIN,{value:Ft.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Ft.SINH,{value:Ft.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Ft.COS,{value:Ft.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Ft.COSH,{value:Ft.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Ft.TAN,{value:Ft.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Ft.TANH,{value:Ft.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Ft.ACOS,{value:Ft.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Ft.ASIN,{value:Ft.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Ft.ATAN,{value:Ft.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Ft.ATAN2,{value:Ft.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Ft.EXP,{value:Ft.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Ft.EXPM1,{value:Ft.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Ft.SQRT,{value:Ft.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Ft.CBRT,{value:Ft.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Ft.GET_EXP,{value:Ft.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Ft.HYPOT,{value:Ft.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Ft.LOG,{value:Ft.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Ft.LOG10,{value:Ft.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Ft.LOG1P,{value:Ft.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Ft.CEIL,{value:Ft.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Ft.FLOOR,{value:Ft.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Ft.FLOOR_DIV,{value:Ft.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Ft.FLOOR_MOD,{value:Ft.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Ft.ABS,{value:Ft.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Ft.MIN,{value:Ft.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Ft.MAX,{value:Ft.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Ft.POW,{value:Ft.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Ft.SIGNUM,{value:Ft.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Ft.RAD,{value:Ft.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Ft.DEG,{value:Ft.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Lt,kt;!function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Lt||(Lt={})),function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(kt||(kt={}));const It=new Map([[Lt.ATTRIBUTE,"tb.rulenode.attribute-type"],[Lt.TIME_SERIES,"tb.rulenode.time-series-type"],[Lt.CONSTANT,"tb.rulenode.constant-type"],[Lt.MESSAGE_BODY,"tb.rulenode.message-body-type"],[Lt.MESSAGE_METADATA,"tb.rulenode.message-metadata-type"]]),Tt=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var Nt,qt;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(Nt||(Nt={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(qt||(qt={}));const St=new Map([[Nt.SHARED_SCOPE,"tb.rulenode.shared-scope"],[Nt.SERVER_SCOPE,"tb.rulenode.server-scope"],[Nt.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class Mt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=tt,this.perimeterTypes=Object.keys(tt),this.perimeterTypeTranslationMap=rt,this.rangeUnits=Object.keys(ot),this.rangeUnitTranslationMap=it,this.timeUnits=Object.keys(nt),this.timeUnitsTranslationMap=at}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[G.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[G.required]],perimeterType:[e?e.perimeterType:null,[G.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[G.required,G.min(1),G.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[G.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[G.required,G.min(1),G.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[G.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,r=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([G.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||r!==tt.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([G.required,G.min(-90),G.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([G.required,G.min(-180),G.max(180)]),this.geoActionConfigForm.get("range").setValidators([G.required,G.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([G.required])),t||r!==tt.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([G.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",Mt),Mt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Mt,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mt,decorators:[{type:r,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class At extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.logConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",n=this.logConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.logConfigForm.get(t).setValue(e)}))}onValidate(){this.logConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",At),At.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:At,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),At.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:At,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:At,decorators:[{type:r,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Gt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[G.required,G.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[G.required]]})}}e("MsgCountConfigComponent",Gt),Gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Gt,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gt,decorators:[{type:r,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Et extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[G.required,G.min(1),G.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([G.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([G.required,G.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",Et),Et.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Et,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Et.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Et,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Et,decorators:[{type:r,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Dt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]]})}}e("PushToCloudConfigComponent",Dt),Dt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Dt,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dt,decorators:[{type:r,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Vt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]]})}}e("PushToEdgeConfigComponent",Vt),Vt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Vt,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vt,decorators:[{type:r,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Pt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",Pt),Pt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Pt,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pt,decorators:[{type:r,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Rt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[G.required,G.min(0)]]})}}e("RpcRequestConfigComponent",Rt),Rt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Rt,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rt,decorators:[{type:r,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class wt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(E),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const r of Object.keys(e))Object.prototype.hasOwnProperty.call(e,r)&&t.push(this.fb.group({key:[r,[G.required]],value:[e[r],[G.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[G.required]],value:["",[G.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",wt),wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wt,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:wt,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:D,useExisting:o((()=>wt)),multi:!0},{provide:V,useExisting:o((()=>wt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#0000008a;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:de.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ce.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wt,decorators:[{type:r,args:[{selector:"tb-kv-map-config",providers:[{provide:D,useExisting:o((()=>wt)),multi:!0},{provide:V,useExisting:o((()=>wt)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#0000008a;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class Ot extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[G.required,G.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[G.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",Ot),Ot.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ot,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ot.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ot,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ot,decorators:[{type:r,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ht extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[G.required,G.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Ht),Ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ht,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ht,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ht,decorators:[{type:r,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Kt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[G.required,G.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[G.required,G.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Kt),Kt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Kt,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kt,decorators:[{type:r,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Bt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[G.required]],keys:[e?e.keys:null,[G.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",Bt),Bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Bt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Bt,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Bt,decorators:[{type:r,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:a,args:["attributeChipList"]}]}});class Ut extends b{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=vt,this.ArgumentType=Lt,this.attributeScopeMap=St,this.argumentTypeResultMap=It,this.arguments=Object.values(Lt),this.attributeScope=Object.values(Nt),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.ngControl=this.injector.get(E),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray(),r=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,r),this.updateArgumentNames()}argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormGroup.get("arguments").controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,r)=>{t.push(this.createArgumentControl(e,r))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormGroup.get("arguments").removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormGroup.get("arguments"),r=this.createArgumentControl(null,t.length);t.push(r,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Ft.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([G.minLength(this.minArgs),G.maxLength(this.maxArgs)]),this.argumentsFormGroup.get("arguments").value.length>this.maxArgs&&(this.argumentsFormGroup.get("arguments").controls.length=this.maxArgs);this.argumentsFormGroup.get("arguments").value.length{this.updateArgumentControlValidators(r),r.get("attributeScope").updateValueAndValidity({emitEvent:!1}),r.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),r}updateArgumentControlValidators(e){const t=e.get("type").value;t===Lt.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==Lt.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormGroup.get("arguments").controls.forEach(((e,t)=>{e.get("name").setValue(Tt[t])}))}updateModel(){const e=this.argumentsFormGroup.get("arguments").value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Ut),Ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ut,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ut,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:D,useExisting:o((()=>Ut)),multi:!0},{provide:V,useExisting:o((()=>Ut)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"],dependencies:[{kind:"directive",type:R.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:de.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:fe.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:fe.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:ge.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:ge.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:ge.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ce.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ut,decorators:[{type:r,args:[{selector:"tb-arguments-map-config",providers:[{provide:D,useExisting:o((()=>Ut)),multi:!0},{provide:V,useExisting:o((()=>Ut)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class zt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.injector=r,this.fb=n,this.searchText="",this.dirty=!1,this.mathOperation=[...vt.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(ye((e=>{let t;t="string"==typeof e&&Ft[e]?Ft[e]:null,this.updateView(t)})),xe((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=vt.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",zt),zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zt,deps:[{token:M.Store},{token:U.TranslateService},{token:t.Injector},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:zt,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:D,useExisting:o((()=>zt)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zt,decorators:[{type:r,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:D,useExisting:o((()=>zt)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:t.Injector},{type:A.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:a,args:["operationInput",{static:!0}]}]}});class jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Ft,this.ArgumentTypeResult=kt,this.argumentTypeResultMap=It,this.attributeScopeMap=St,this.argumentsResult=Object.values(kt),this.attributeScopeResult=Object.values(qt)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[G.required]],arguments:[e?e.arguments:null,[G.required]],customFunction:[e?e.customFunction:"",[G.required]],result:this.fb.group({type:[e?e.result.type:null,[G.required]],attributeScope:[e?e.result.attributeScope:null,[G.required]],key:[e?e.result.key:"",[G.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,r=this.mathFunctionConfigForm.get("result.type").value;t===Ft.CUSTOM?this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),r===kt.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",jt),jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:jt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:jt,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:A.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ut,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:zt,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:jt,decorators:[{type:r,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class _t{constructor(e,t){this.store=e,this.fb=t,this.subscriptSizing="fixed",this.searchText="",this.dirty=!1,this.messageTypes=["POST_ATTRIBUTES_REQUEST","POST_TELEMETRY_REQUEST"],this.propagateChange=e=>{},this.messageTypeFormGroup=this.fb.group({messageType:[null,[G.required,G.maxLength(255)]]})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.outputMessageTypes=this.messageTypeFormGroup.get("messageType").valueChanges.pipe(ye((e=>{this.updateView(e)})),xe((e=>e||"")),be((e=>this.fetchMessageTypes(e))))}writeValue(e){this.searchText="",this.modelValue=e,this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1}),this.dirty=!0}onFocus(){this.dirty&&(this.messageTypeFormGroup.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0}),this.dirty=!1)}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}displayMessageTypeFn(e){return e||void 0}fetchMessageTypes(e,t=!1){return this.searchText=e,ke(this.messageTypes).pipe(xe((r=>r.filter((r=>t?!!e&&r===e:!e||r.toUpperCase().startsWith(e.toUpperCase()))))))}clear(){this.messageTypeFormGroup.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}}e("OutputMessageTypeAutocompleteComponent",_t),_t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_t,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:_t,selector:"tb-output-message-type-autocomplete",inputs:{autocompleteHint:"autocompleteHint",subscriptSizing:"subscriptSizing"},providers:[{provide:D,useExisting:o((()=>_t)),multi:!0}],viewQueries:[{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0,static:!0}],ngImport:t,template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_t,decorators:[{type:r,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:D,useExisting:o((()=>_t)),multi:!0}],template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{messageTypeInput:[{type:a,args:["messageTypeInput",{static:!0}]}],autocompleteHint:[{type:i}],subscriptSizing:[{type:i}]}});class $t extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.destroy$=new Ie,this.serviceType=p.TB_RULE_ENGINE,this.deduplicationStrategie=mt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=ut}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[Y(e?.interval)?e.interval:null,[G.required,G.min(1)]],strategy:[Y(e?.strategy)?e.strategy:null,[G.required]],outMsgType:[Y(e?.outMsgType)?e.outMsgType:null,[G.required]],queueName:[Y(e?.queueName)?e.queueName:null,[G.required]],maxPendingMsgs:[Y(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[G.required,G.min(1),G.max(1e3)]],maxRetries:[Y(e?.maxRetries)?e.maxRetries:null,[G.required,G.min(0),G.max(100)]]}),this.deduplicationConfigForm.get("strategy").valueChanges.pipe(he(this.destroy$)).subscribe((e=>{this.enableControl(e)}))}updateValidators(e){this.enableControl(this.deduplicationConfigForm.get("strategy").value)}validatorTriggers(){return["strategy"]}enableControl(e){e===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("DeduplicationConfigComponent",$t),$t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$t,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:$t,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:_t,selector:"tb-output-message-type-autocomplete",inputs:["autocompleteHint","subscriptSizing"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$t,decorators:[{type:r,args:[{selector:"tb-action-node-msg-deduplication-config",template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Jt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[G.required]],maxLevel:[null,[]],relationType:[null],deviceTypes:[null,[G.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",Jt),Jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Jt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Jt,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:D,useExisting:o((()=>Jt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-type
\n \n \n
device.device-types
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:qe.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","disabled","entityType"]},{kind:"component",type:Se.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["required","disabled","subscriptSizing"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Jt,decorators:[{type:r,args:[{selector:"tb-device-relations-query-config",providers:[{provide:D,useExisting:o((()=>Jt)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-type
\n \n \n
device.device-types
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Qt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[G.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",Qt),Qt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qt,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Qt,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:D,useExisting:o((()=>Qt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Me.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qt,decorators:[{type:r,args:[{selector:"tb-relations-query-config",providers:[{provide:D,useExisting:o((()=>Qt)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Yt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t,r,n){super(e),this.store=e,this.translate=t,this.truncate=r,this.fb=n,this.placeholder="tb.rulenode.message-type",this.separatorKeysCodes=[ne,ae,oe],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(h))this.messageTypesList.push({name:C.get(h[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchMessageTypes(e))),Fe())}ngAfterViewInit(){}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return!!(e&&null!=e&&e.length>0)}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return ke(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t=null;const r=e.trim(),n=this.messageTypesList.find((e=>e.name===r));t=n?{name:n.name,value:n.value}:{name:r,value:r},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Yt),Yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Yt,deps:[{token:M.Store},{token:U.TranslateService},{token:F.TruncatePipe},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Yt,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:D,useExisting:o((()=>Yt)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) | async }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Yt,decorators:[{type:r,args:[{selector:"tb-message-types-config",providers:[{provide:D,useExisting:o((()=>Yt)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) | async }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:F.TruncatePipe},{type:A.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:a,args:["chipList",{static:!1}]}],matAutocomplete:[{type:a,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:a,args:["messageTypeInput",{static:!1}]}]}});class Wt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ue(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=ft,this.credentialsTypeTranslationsMap=gt,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[G.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const r=e[t];if(!r.firstChange&&r.currentValue!==r.previousValue&&r.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){Y(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([G.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[G.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(G.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return r=>{t||(t=[Object.keys(r.controls)]);return r?.controls&&t.some((t=>t.every((t=>!e(r.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",Wt),Wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Wt,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Wt,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:D,useExisting:o((()=>Wt)),multi:!0},{provide:V,useExisting:o((()=>Wt)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:R.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:R.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Te.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Wt,decorators:[{type:r,args:[{selector:"tb-credentials-config",providers:[{provide:D,useExisting:o((()=>Wt)),multi:!0},{provide:V,useExisting:o((()=>Wt)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});class Xt{}e("RulenodeCoreConfigCommonModule",Xt),Xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xt,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Xt.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Xt,declarations:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t],imports:[w,v,Ne],exports:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t]}),Xt.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xt,imports:[w,v,Ne]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xt,decorators:[{type:l,args:[{declarations:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t],imports:[w,v,Ne],exports:[wt,Jt,Qt,Yt,Wt,Ue,Ut,zt,_t]}]}]});class Zt{}e("RuleNodeCoreConfigActionModule",Zt),Zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zt,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Zt.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Zt,declarations:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t],imports:[w,v,Ne,Xt],exports:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t]}),Zt.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zt,imports:[w,v,Ne,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zt,decorators:[{type:l,args:[{declarations:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t],imports:[w,v,Ne,Xt],exports:[Bt,je,Ht,Rt,At,ze,$e,Je,Qe,Et,Ye,Xe,Mt,Gt,Pt,Ot,Kt,_e,We,Vt,Dt,jt,$t]}]}]});class er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e?e.inputValueKey:null,[G.required]],outputValueKey:[e?e.outputValueKey:null,[G.required]],useCache:[e?e.useCache:null,[]],addPeriodBetweenMsgs:[!!e&&e.addPeriodBetweenMsgs,[]],periodValueKey:[e?e.periodValueKey:null,[]],round:[e?e.round:null,[G.min(0),G.max(15)]],tellFailureIfDeltaIsNegative:[e?e.tellFailureIfDeltaIsNegative:null,[]]})}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([G.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:er,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:er,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:'
\n
\n \n tb.rulenode.input-value-key\n \n \n {{ \'tb.rulenode.input-value-key-required\' | translate }}\n \n \n \n tb.rulenode.output-value-key\n \n \n {{ \'tb.rulenode.output-value-key-required\' | translate }}\n \n \n \n tb.rulenode.round\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n
\n \n {{ \'tb.rulenode.use-cache\' | translate }}\n \n \n {{ \'tb.rulenode.tell-failure-if-delta-is-negative\' | translate }}\n \n \n {{ \'tb.rulenode.add-period-between-msgs\' | translate }}\n \n \n tb.rulenode.period-value-key\n \n \n {{ \'tb.rulenode.period-value-key-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:er,decorators:[{type:r,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:'
\n
\n \n tb.rulenode.input-value-key\n \n \n {{ \'tb.rulenode.input-value-key-required\' | translate }}\n \n \n \n tb.rulenode.output-value-key\n \n \n {{ \'tb.rulenode.output-value-key-required\' | translate }}\n \n \n \n tb.rulenode.round\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n {{ \'tb.rulenode.round-range\' | translate }}\n \n \n
\n \n {{ \'tb.rulenode.use-cache\' | translate }}\n \n \n {{ \'tb.rulenode.tell-failure-if-delta-is-negative\' | translate }}\n \n \n {{ \'tb.rulenode.add-period-between-msgs\' | translate }}\n \n \n tb.rulenode.period-value-key\n \n \n {{ \'tb.rulenode.period-value-key-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.customerAttributesConfigForm}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("CustomerAttributesConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:tr,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e?e.deviceRelationsQuery:null,[G.required]],tellFailureIfAbsent:[!!e&&e.tellFailureIfAbsent,[]],fetchToData:[!!e&&e.fetchToData,[]],clientAttributeNames:[e?e.clientAttributeNames:null,[]],sharedAttributeNames:[e?e.sharedAttributeNames:null,[]],serverAttributeNames:[e?e.serverAttributeNames:null,[]],latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],getLatestValueWithTs:[!!e&&e.getLatestValueWithTs,[]]})}removeKey(e,t){const r=this.deviceAttributesConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.deviceAttributesConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deviceAttributesConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deviceAttributesConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}prepareInputConfig(e){return W(e)&&X(e?.fetchToData)&&(e.fetchToData=!1),e}}e("DeviceAttributesConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:rr,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Jt,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n \n \n \n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class nr extends s{constructor(e,t,r){super(e),this.store=e,this.translate=t,this.fb=r,this.entityDetailsTranslationsMap=st,this.entityDetailsList=[],this.searchText="",this.displayDetailsFn=this.displayDetails.bind(this);for(const e of Object.keys(lt))this.entityDetailsList.push(lt[e]);this.detailsFormControl=new P(""),this.filteredEntityDetails=this.detailsFormControl.valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchEntityDetails(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){return this.searchText="",this.detailsFormControl.patchValue("",{emitEvent:!0}),this.detailsList=e?e.detailsList:[],e}prepareOutputConfig(e){return e.detailsList=this.detailsList,e}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e?e.detailsList:null,[G.required]],addToMetadata:[!!e&&e.addToMetadata,[]]}),this.detailsList=e?e.detailsList:[]}displayDetails(e){return e?this.translate.instant(st.get(e)):void 0}fetchEntityDetails(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(this.entityDetailsList.filter((t=>this.translate.instant(st.get(lt[t])).toUpperCase().includes(e))))}return ke(this.entityDetailsList)}detailsFieldSelected(e){this.addDetailsField(e.option.value),this.clear("")}removeDetailsField(e){const t=this.detailsList.indexOf(e);t>=0&&(this.detailsList.splice(t,1),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}addDetailsField(e){this.detailsList||(this.detailsList=[]);-1===this.detailsList.indexOf(e)&&(this.detailsList.push(e),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}onEntityDetailsInputFocus(){this.detailsFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.detailsInput.nativeElement.value=e,this.detailsFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}}e("EntityDetailsConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nr,deps:[{token:M.Store},{token:U.TranslateService},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:nr,selector:"tb-enrichment-node-entity-details-config",viewQueries:[{propertyName:"detailsInput",first:!0,predicate:["detailsInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.entity-details\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-entity-details-matching\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n {{ \'tb.rulenode.add-to-metadata\' | translate }}\n \n
tb.rulenode.add-to-metadata-hint
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n tb.rulenode.entity-details\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-entity-details-matching\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n {{ \'tb.rulenode.add-to-metadata\' | translate }}\n \n
tb.rulenode.add-to-metadata-hint
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:A.UntypedFormBuilder}]},propDecorators:{detailsInput:[{type:a,args:["detailsInput",{static:!1}]}]}});class ar extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe],this.aggregationTypes=L,this.aggregations=Object.keys(L),this.aggregationTypesTranslations=k,this.fetchMode=mt,this.fetchModes=Object.keys(mt),this.samplingOrders=Object.keys(pt),this.timeUnits=Object.values(nt),this.timeUnitsTranslationMap=at}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],aggregation:[e?e.aggregation:null,[G.required]],fetchMode:[e?e.fetchMode:null,[G.required]],orderBy:[e?e.orderBy:null,[]],limit:[e?e.limit:null,[]],useMetadataIntervalPatterns:[!!e&&e.useMetadataIntervalPatterns,[]],startInterval:[e?e.startInterval:null,[]],startIntervalTimeUnit:[e?e.startIntervalTimeUnit:null,[]],endInterval:[e?e.endInterval:null,[]],endIntervalTimeUnit:[e?e.endIntervalTimeUnit:null,[]],startIntervalPattern:[e?e.startIntervalPattern:null,[]],endIntervalPattern:[e?e.endIntervalPattern:null,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,r=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===mt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([G.required,G.min(2),G.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),r?(this.getTelemetryFromDatabaseConfigForm.get("startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([G.required])):(this.getTelemetryFromDatabaseConfigForm.get("startInterval").setValidators([G.required,G.min(1),G.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("endInterval").setValidators([G.required,G.min(1),G.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").setValidators([G.required]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const r=this.getTelemetryFromDatabaseConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}}e("GetTelemetryFromDatabaseConfigComponent",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ar,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ar,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeseries-key\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.fetch-mode\n \n \n {{ mode }}\n \n \n tb.rulenode.fetch-mode-hint\n \n
\n \n aggregation.function\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n \n tb.rulenode.order-by\n \n \n {{ order }}\n \n \n tb.rulenode.order-by-hint\n \n \n tb.rulenode.limit\n \n tb.rulenode.limit-hint\n \n
\n \n {{ \'tb.rulenode.use-metadata-interval-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-interval-patterns-hint
\n
\n
\n \n tb.rulenode.start-interval\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.start-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.end-interval\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.end-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n \n tb.rulenode.start-interval-pattern\n \n \n {{ \'tb.rulenode.start-interval-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.end-interval-pattern\n \n \n {{ \'tb.rulenode.end-interval-pattern-required\' | translate }}\n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ar,decorators:[{type:r,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n tb.rulenode.timeseries-key\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.fetch-mode\n \n \n {{ mode }}\n \n \n tb.rulenode.fetch-mode-hint\n \n
\n \n aggregation.function\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n \n tb.rulenode.order-by\n \n \n {{ order }}\n \n \n tb.rulenode.order-by-hint\n \n \n tb.rulenode.limit\n \n tb.rulenode.limit-hint\n \n
\n \n {{ \'tb.rulenode.use-metadata-interval-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-interval-patterns-hint
\n
\n
\n \n tb.rulenode.start-interval\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.start-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.end-interval\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.end-interval-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n \n tb.rulenode.start-interval-pattern\n \n \n {{ \'tb.rulenode.start-interval-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.end-interval-pattern\n \n \n {{ \'tb.rulenode.end-interval-pattern-required\' | translate }}\n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[!!e&&e.tellFailureIfAbsent,[]],fetchToData:[!!Y(e?.fetchToData)&&e.fetchToData,[]],clientAttributeNames:[e?e.clientAttributeNames:null,[]],sharedAttributeNames:[e?e.sharedAttributeNames:null,[]],serverAttributeNames:[e?e.serverAttributeNames:null,[]],latestTsKeyNames:[e?e.latestTsKeyNames:null,[]],getLatestValueWithTs:[!!e&&e.getLatestValueWithTs,[]]})}removeKey(e,t){const r=this.originatorAttributesConfigForm.get(t).value,n=r.indexOf(e);n>=0&&(r.splice(n,1),this.originatorAttributesConfigForm.get(t).setValue(r,{emitEvent:!0}))}addKey(e,t){const r=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.originatorAttributesConfigForm.get(t).value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.originatorAttributesConfigForm.get(t).setValue(e,{emitEvent:!0}))}r&&(r.value="")}prepareInputConfig(e){return W(e)&&X(e?.fetchToData)&&(e.fetchToData=!1),e}}e("OriginatorAttributesConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:or,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:or,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:or,decorators:[{type:r,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n \n {{ \'tb.rulenode.tell-failure-if-absent\' | translate }}\n \n
tb.rulenode.tell-failure-if-absent-hint
\n
{{ \'tb.rulenode.fetch-into\' | translate }}
\n \n \n {{ \'tb.rulenode.data\' | translate }}\n \n \n {{ \'tb.rulenode.metadata\' | translate }}\n \n \n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-timeseries\n \n \n {{key}}\n close\n \n \n \n \n \n \n {{ \'tb.rulenode.get-latest-value-with-ts\' | translate }}\n \n
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.originatorFieldsConfigForm}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({fieldsMapping:[e?e.fieldsMapping:null,[G.required]],ignoreNullStrings:[e?e.ignoreNullStrings:null]})}}e("OriginatorFieldsConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ir,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ir,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n {{ "tb.rulenode.ignore-null-strings" | translate }}\n
{{ "tb.rulenode.ignore-null-strings-hint" | translate }}
\n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ir,decorators:[{type:r,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n {{ "tb.rulenode.ignore-null-strings" | translate }}\n
{{ "tb.rulenode.ignore-null-strings-hint" | translate }}
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class lr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.relatedAttributesConfigForm}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e?e.relationsQuery:null,[G.required]],telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("RelatedAttributesConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:lr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:lr,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"component",type:Qt,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:lr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n \n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class sr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.tenantAttributesConfigForm}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({telemetry:[!!e&&e.telemetry,[]],attrMapping:[e?e.attrMapping:null,[G.required]]})}}e("TenantAttributesConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:sr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:sr,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:sr,decorators:[{type:r,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n \n \n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class mr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchToMetadata:[e?e.fetchToMetadata:null,[]]})}}e("FetchDeviceCredentialsConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:mr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:mr,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n {{ \'tb.rulenode.fetch-credentials-to-metadata\' | translate }}\n
\n',dependencies:[{kind:"component",type:De.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:mr,decorators:[{type:r,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n {{ \'tb.rulenode.fetch-credentials-to-metadata\' | translate }}\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class ur{}e("RulenodeCoreConfigEnrichmentModule",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:ur,declarations:[tr,nr,rr,or,ir,ar,lr,sr,er,mr],imports:[w,v,Xt],exports:[tr,nr,rr,or,ir,ar,lr,sr,er,mr]}),ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,decorators:[{type:l,args:[{declarations:[tr,nr,rr,or,ir,ar,lr,sr,er,mr],imports:[w,v,Xt],exports:[tr,nr,rr,or,ir,ar,lr,sr,er,mr]}]}]});class pr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=yt,this.azureIotHubCredentialsTypeTranslationsMap=xt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[G.required,G.min(1),G.max(200)]],clientId:[e?e.clientId:null,[G.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[G.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),r=t.get("type").value;switch(e&&t.reset({type:r},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),r){case"sas":t.get("sasKey").setValidators([G.required]);break;case"cert.PEM":t.get("privateKey").setValidators([G.required]),t.get("privateKeyFileName").setValidators([G.required]),t.get("cert").setValidators([G.required]),t.get("certFileName").setValidators([G.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:pr,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:R.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:R.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Te.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Te.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Te.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Te.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Te.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:A.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pr,decorators:[{type:r,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class dr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=ht,this.ToByteStandartCharsetTypeTranslationMap=Ct}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[G.required]],retries:[e?e.retries:null,[G.min(0)]],batchSize:[e?e.batchSize:null,[G.min(0)]],linger:[e?e.linger:null,[G.min(0)]],bufferMemory:[e?e.bufferMemory:null,[G.min(0)]],acks:[e?e.acks:null,[G.required]],keySerializer:[e?e.keySerializer:null,[G.required]],valueSerializer:[e?e.valueSerializer:null,[G.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([G.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:dr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:dr,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:dr,decorators:[{type:r,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class cr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[]}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[G.required]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[G.required,G.min(1),G.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&Z(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]}),this.subscriptions.push(this.mqttConfigForm.get("clientId").valueChanges.subscribe((e=>{Z(e)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1})})))}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}}e("MqttConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:cr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:cr,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Wt,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:cr,decorators:[{type:r,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class fr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=I,this.entityType=x}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[G.required]],targets:[e?e.targets:[],[G.required]]})}}e("NotificationConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:fr,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:fr,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:Ve.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Pe.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","disabled","notificationTypes"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:fr,decorators:[{type:r,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]}});class gr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[G.required]],topicName:[e?e.topicName:null,[G.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[G.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[G.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:gr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:gr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ae.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:gr,decorators:[{type:r,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class yr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[G.required]],port:[e?e.port:null,[G.required,G.min(1),G.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[G.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[G.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:yr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:yr,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:yr,decorators:[{type:r,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class xr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(bt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[G.required]],requestMethod:[e?e.requestMethod:null,[G.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],trimDoubleQuotes:[!!e&&e.trimDoubleQuotes,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[G.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,r=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,n=this.restApiCallConfigForm.get("enableProxy").value,a=this.restApiCallConfigForm.get("useSystemProxyProperties").value;n&&!a?(this.restApiCallConfigForm.get("proxyHost").setValidators(n?[G.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(n?[G.required,G.min(1),G.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([G.min(0)])),r?this.restApiCallConfigForm.get("maxQueueSize").setValidators([G.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:xr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:xr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"component",type:Wt,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:xr,decorators:[{type:r,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class br extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,r=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([G.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([G.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([G.required,G.min(1),G.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([G.required,G.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(r?[G.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(r?[G.required,G.min(1),G.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:br,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:br,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Re.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:K.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ge.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:br,decorators:[{type:r,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class hr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[G.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[G.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([G.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:hr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:hr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:we.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:hr,decorators:[{type:r,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Cr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(T),this.slackChanelTypesTranslateMap=N}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[G.required]],conversationType:[e?e.conversationType:null,[G.required]],conversation:[e?e.conversation:null,[G.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([G.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Cr,deps:[{token:M.Store},{token:A.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Cr,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Oe.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Cr,decorators:[{type:r,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.FormBuilder}]}});class Fr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[G.required]],accessKeyId:[e?e.accessKeyId:null,[G.required]],secretAccessKey:[e?e.secretAccessKey:null,[G.required]],region:[e?e.region:null,[G.required]]})}}e("SnsConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Fr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Fr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Fr,decorators:[{type:r,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class vr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=dt,this.sqsQueueTypes=Object.keys(dt),this.sqsQueueTypeTranslationsMap=ct}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[G.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[G.required]],delaySeconds:[e?e.delaySeconds:null,[G.min(0),G.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[G.required]],secretAccessKey:[e?e.secretAccessKey:null,[G.required]],region:[e?e.region:null,[G.required]]})}}e("SqsConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:vr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:vr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:vr,decorators:[{type:r,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Lr{}e("RulenodeCoreConfigExternalModule",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Lr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Lr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Lr,declarations:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr],imports:[w,v,Ne,Xt],exports:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr]}),Lr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Lr,imports:[w,v,Ne,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Lr,decorators:[{type:l,args:[{declarations:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr],imports:[w,v,Ne,Xt],exports:[Fr,vr,gr,dr,cr,fr,yr,xr,br,pr,hr,Cr]}]}]});class kr extends s{constructor(e,t,r){super(e),this.store=e,this.translate=t,this.fb=r,this.alarmStatusTranslationsMap=q,this.alarmStatusList=[],this.searchText="",this.displayStatusFn=this.displayStatus.bind(this);for(const e of Object.keys(S))this.alarmStatusList.push(S[e]);this.statusFormControl=new P(""),this.filteredAlarmStatus=this.statusFormControl.valueChanges.pipe(Ce(""),xe((e=>e||"")),be((e=>this.fetchAlarmStatus(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return this.searchText="",this.statusFormControl.patchValue("",{emitEvent:!0}),e}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e?e.alarmStatusList:null,[G.required]]})}displayStatus(e){return e?this.translate.instant(q.get(e)):void 0}fetchAlarmStatus(e){const t=this.getAlarmStatusList();if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return ke(t.filter((t=>this.translate.instant(q.get(S[t])).toUpperCase().includes(e))))}return ke(t)}alarmStatusSelected(e){this.addAlarmStatus(e.option.value),this.clear("")}removeAlarmStatus(e){const t=this.alarmStatusConfigForm.get("alarmStatusList").value;if(t){const r=t.indexOf(e);r>=0&&(t.splice(r,1),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}}addAlarmStatus(e){let t=this.alarmStatusConfigForm.get("alarmStatusList").value;t||(t=[]);-1===t.indexOf(e)&&(t.push(e),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}getAlarmStatusList(){return this.alarmStatusList.filter((e=>-1===this.alarmStatusConfigForm.get("alarmStatusList").value.indexOf(e)))}onAlarmStatusInputFocus(){this.statusFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.alarmStatusInput.nativeElement.value=e,this.statusFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.alarmStatusInput.nativeElement.blur(),this.alarmStatusInput.nativeElement.focus()}),0)}}e("CheckAlarmStatusComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:kr,deps:[{token:M.Store},{token:U.TranslateService},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:kr,selector:"tb-filter-node-check-alarm-status-config",viewQueries:[{propertyName:"alarmStatusInput",first:!0,predicate:["alarmStatusInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:R.AsyncPipe,name:"async"},{kind:"pipe",type:Le.HighlightPipe,name:"highlight"},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:kr,decorators:[{type:r,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:U.TranslateService},{type:A.UntypedFormBuilder}]},propDecorators:{alarmStatusInput:[{type:a,args:["alarmStatusInput",{static:!1}]}]}});class Ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}configForm(){return this.checkMessageConfigForm}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e?e.messageNames:null,[]],metadataNames:[e?e.metadataNames:null,[]],checkAllKeys:[!!e&&e.checkAllKeys,[]]})}validateConfig(){const e=this.checkMessageConfigForm.get("messageNames").value,t=this.checkMessageConfigForm.get("metadataNames").value;return e.length>0||t.length>0}removeMessageName(e){const t=this.checkMessageConfigForm.get("messageNames").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.checkMessageConfigForm.get("messageNames").setValue(t,{emitEvent:!0}))}removeMetadataName(e){const t=this.checkMessageConfigForm.get("metadataNames").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.checkMessageConfigForm.get("metadataNames").setValue(t,{emitEvent:!0}))}addMessageName(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.checkMessageConfigForm.get("messageNames").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.checkMessageConfigForm.get("messageNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}addMetadataName(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.checkMessageConfigForm.get("metadataNames").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.checkMessageConfigForm.get("metadataNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CheckMessageConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ir,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ir,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ir,decorators:[{type:r,args:[{selector:"tb-filter-node-check-message-config",template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.keys(g),this.entitySearchDirectionTranslationsMap=y}configForm(){return this.checkRelationConfigForm}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[!!e&&e.checkForSingleEntity,[]],direction:[e?e.direction:null,[]],entityType:[e?e.entityType:null,e&&e.checkForSingleEntity?[G.required]:[]],entityId:[e?e.entityId:null,e&&e.checkForSingleEntity?[G.required]:[]],relationType:[e?e.relationType:null,[G.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[G.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[G.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Tr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Tr,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Se.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["required","disabled","subscriptSizing"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Tr,decorators:[{type:r,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Nr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=tt,this.perimeterTypes=Object.keys(tt),this.perimeterTypeTranslationMap=rt,this.rangeUnits=Object.keys(ot),this.rangeUnitTranslationMap=it}configForm(){return this.geoFilterConfigForm}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[G.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[G.required]],perimeterType:[e?e.perimeterType:null,[G.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,r=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([G.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||r!==tt.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([])):(this.geoFilterConfigForm.get("centerLatitude").setValidators([G.required,G.min(-90),G.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([G.required,G.min(-180),G.max(180)]),this.geoFilterConfigForm.get("range").setValidators([G.required,G.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([G.required])),t||r!==tt.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([G.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",Nr),Nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Nr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Nr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:O.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:A.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Nr,decorators:[{type:r,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class qr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e?e.messageTypes:null,[G.required]]})}}e("MessageTypeConfigComponent",qr),qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:qr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),qr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:qr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Yt,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:qr,decorators:[{type:r,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Sr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.TENANT,x.CUSTOMER,x.USER,x.DASHBOARD,x.RULE_CHAIN,x.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e?e.originatorTypes:null,[G.required]]})}}e("OriginatorTypeConfigComponent",Sr),Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Sr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Sr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n
\n',dependencies:[{kind:"component",type:Ke.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","disabled","subscriptSizing","allowedEntityTypes","ignoreAuthorityFilter"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Sr,decorators:[{type:r,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Mr extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",n=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Mr),Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mr,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Mr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mr,decorators:[{type:r,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Ar extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.switchConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",n=this.switchConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.switchConfigForm.get(t).setValue(e)}))}onValidate(){this.switchConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Ar),Ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ar,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ar,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ar,decorators:[{type:r,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Gr{}e("RuleNodeCoreConfigFilterModule",Gr),Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Gr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Gr,declarations:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr],imports:[w,v,Xt],exports:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr]}),Gr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gr,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gr,decorators:[{type:l,args:[{declarations:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr],imports:[w,v,Xt],exports:[Ir,Tr,Nr,qr,Sr,Mr,Ar,kr]}]}]});class Er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=Ze,this.originatorSources=Object.keys(Ze),this.originatorSourceTranslationMap=et,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.USER,x.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[G.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===Ze.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([G.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===Ze.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([G.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([G.required,G.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Er),Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Er,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Er,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:se.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:B.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Er,decorators:[{type:r,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Dr extends s{constructor(e,t,r,n){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=r,this.translate=n,this.tbelEnabled=J(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[G.required]],jsScript:[e?e.jsScript:null,[G.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[G.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[G.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",r=e===d.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",n=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(n,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Dr),Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dr,deps:[{token:M.Store},{token:A.UntypedFormBuilder},{token:Q.NodeScriptTestService},{token:U.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Dr,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ee.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:te.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dr,decorators:[{type:r,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder},{type:Q.NodeScriptTestService},{type:U.TranslateService}]},propDecorators:{jsFuncComponent:[{type:a,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:a,args:["tbelFuncComponent",{static:!1}]}]}});class Vr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",value:"false"},{name:"tb.mail-body-type.html",value:"true"},{name:"tb.mail-body-type.dynamic",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[G.required]],toTemplate:[e?e.toTemplate:null,[G.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[G.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null],bodyTemplate:[e?e.bodyTemplate:null,[G.required]]}),this.toEmailConfigForm.get("mailBodyType").valueChanges.pipe(Ce([e?.subjectTemplate])).subscribe((e=>{"dynamic"===e?(this.toEmailConfigForm.get("isHtmlTemplate").patchValue("",{emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").setValidators(G.required)):this.toEmailConfigForm.get("isHtmlTemplate").clearValidators(),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity()}))}}e("ToEmailConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Vr,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:j.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:_.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:U.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vr,decorators:[{type:r,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Pr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],keys:[e?e.keys:null,[G.required]]})}configForm(){return this.copyKeysConfigForm}removeKey(e){const t=this.copyKeysConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.copyKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.copyKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.copyKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CopyKeysConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Pr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pr,decorators:[{type:r,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[G.required]]})}}e("RenameKeysConfigComponent",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Rr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:wt,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rr,decorators:[{type:r,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class wr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[G.required]]})}}e("NodeJsonPathConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:wr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n",dependencies:[{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatLabel,selector:"mat-label"},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wr,decorators:[{type:r,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n"}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ne,ae,oe]}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[G.required]],keys:[e?e.keys:null,[G.required]]})}configForm(){return this.deleteKeysConfigForm}removeKey(e){const t=this.deleteKeysConfigForm.get("keys").value,r=t.indexOf(e);r>=0&&(t.splice(r,1),this.deleteKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.deleteKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.deleteKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteKeysConfigComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Or,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ie.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:H.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:K.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:K.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:K.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ee.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ee.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:le.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:le.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:le.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:le.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:B.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"},{kind:"pipe",type:Ue,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Or,decorators:[{type:r,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Hr{}e("RulenodeCoreConfigTransformModule",Hr),Hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Hr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Hr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Hr,declarations:[Er,Dr,Vr,Pr,Rr,wr,Or],imports:[w,v,Xt],exports:[Er,Dr,Vr,Pr,Rr,wr,Or]}),Hr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Hr,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Hr,decorators:[{type:l,args:[{declarations:[Er,Dr,Vr,Pr,Rr,wr,Or],imports:[w,v,Xt],exports:[Er,Dr,Vr,Pr,Rr,wr,Or]}]}]});class Kr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=x}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[G.required]]})}}e("RuleChainInputComponent",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kr,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Kr,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:He.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:A.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kr,decorators:[{type:r,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Br extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Br,deps:[{token:M.Store},{token:A.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Br,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:B.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:A.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:A.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:U.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Br,decorators:[{type:r,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:M.Store},{type:A.UntypedFormBuilder}]}});class Ur{}e("RuleNodeCoreConfigFlowModule",Ur),Ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Ur,declarations:[Kr,Br],imports:[w,v,Xt],exports:[Kr,Br]}),Ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ur,imports:[w,v,Xt]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ur,decorators:[{type:l,args:[{declarations:[Kr,Br],imports:[w,v,Xt],exports:[Kr,Br]}]}]});class zr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{"create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","output-message-type":"Output message type","output-message-type-required":"Output message type is required","output-message-type-max-length":"Output message type should be less than 256","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","start-interval":"Start Interval","end-interval":"End Interval","start-interval-time-unit":"Start Interval Time Unit","end-interval-time-unit":"End Interval Time Unit","fetch-mode":"Fetch mode","fetch-mode-hint":"If selected fetch mode 'ALL' you able to choose telemetry sampling order.","order-by":"Order by","order-by-hint":"Select to choose telemetry sampling order.",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. In case you want to fetch a single entry, select fetch mode 'FIRST' or 'LAST'.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Time value should be in a range from 1 to 2147483647.","start-interval-value-required":"Start interval value is required.","end-interval-value-required":"End interval value is required.",filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attribute keys","shared-attributes":"Shared attribute keys","server-attributes":"Server attribute keys","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Notify device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-hint":"If the message arrives from the device, we will push it back to the device by default.","notify-device-delete-hint":"Send notification about deleted attributes to device.","latest-timeseries":"Latest time-series data keys","timeseries-key":"Time-series key","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Hint: use regular expression to copy keys by pattern",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.","first-message":"First Message","last-message":"Last Message","all-messages":"All Messages","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",metadata:"Metadata","key-name":"Key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern","fetch-into":"Fetch into","attr-mapping":"Attributes mapping","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-attribute":"Target attribute","target-attribute-required":"Target attribute is required.","attr-mapping-required":"At least one attribute mapping should be specified.","fields-mapping":"Fields mapping","fields-mapping-required":"At least one field mapping should be specified.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","body-template":"Body Template","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","trim-double-quotes":"Message without quotes","trim-double-quotes-hint":"If selected, request body message payload will be sent without double quotes, i.e. msg = message body","read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Hint: Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Hint: Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Hint: Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-interval-patterns":"Use interval patterns","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval-pattern":"Start interval pattern","end-interval-pattern":"End interval pattern","start-interval-pattern-required":"Start interval pattern is required","end-interval-pattern-required":"End interval pattern is required","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"entity-details":"Select entity details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","add-to-metadata":"Add selected details to message metadata","add-to-metadata-hint":"If selected, adds the selected details keys to the message metadata instead of message data.","entity-details-list-empty":"No entity details selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-key-name":"Latitude key name","longitude-key-name":"Longitude key name","latitude-key-name-required":"Latitude key name is required.","longitude-key-name-required":"Longitude key name is required.","fetch-perimeter-info-from-message-metadata":"Fetch perimeter information from message metadata","perimeter-key-name":"Perimeter key name","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Please, use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.",round:"Decimals","round-range":"Decimals should be in a range from 0 to 15.","use-cache":"Use cache for latest value","tell-failure-if-delta-is-negative":"Tell Failure if delta is negative","add-period-between-msgs":"Add period between messages","period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"alarm-severity-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body to substitute "Source" and "Target" key names',"shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time series","message-body-type":"Message body","message-metadata-type":"Message metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-type-field-input":"Type","argument-type-field-input-required":"Argument type is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Hint: use 0 to convert result to integer","add-to-body-field-input":"Add to message body","add-to-metadata-field-input":"Add to message metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Hint: specify a mathematical expression to evaluate. For example, transform Fahrenheit to Celsius using (x - 32) / 1.8)","retained-message":"Retained","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required"},"key-val":{key:"Key",value:"Value","remove-entry":"Remove entry","add-entry":"Add entry","unique-key-value-pair-error":"'{{valText}}' must be different from the current '{{keyText}}'"},"mail-body-type":{"plain-text":"Plain Text",html:"HTML",dynamic:"Dynamic"}}},!0)}(e)}}e("RuleNodeCoreConfigModule",zr),zr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zr,deps:[{token:U.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),zr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:zr,declarations:[Be],imports:[w,v],exports:[Zt,Gr,ur,Lr,Hr,Ur,Be]}),zr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zr,imports:[w,v,Zt,Gr,ur,Lr,Hr,Ur]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zr,decorators:[{type:l,args:[{declarations:[Be],imports:[w,v],exports:[Zt,Gr,ur,Lr,Hr,Ur,Be]}]}],ctorParameters:function(){return[{type:U.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map From a85f5b433099003d802a244daff4eed48f7b971d Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 8 Jun 2023 12:30:35 +0300 Subject: [PATCH 149/207] added initial implementation --- application/pom.xml | 4 + .../ThingsboardSecurityConfiguration.java | 5 +- .../server/controller/AdminController.java | 130 +++++- .../MailConfigTemplateController.java | 82 ++++ .../service/mail/DefaultMailService.java | 71 +-- .../DefaultTbMailConfigTemplateService.java | 19 + .../mail/RefreshTokenExpCheckService.java | 75 ++++ .../mail/TbMailConfigTemplateService.java | 9 + .../service/mail/TbMailContextComponent.java | 32 ++ .../server/service/mail/TbMailSender.java | 168 ++++++++ .../templates/mail_config_templates.json | 52 +++ .../src/main/resources/thingsboard.yml | 4 + .../server/common/data/StringUtils.java | 7 + .../common/data/mail/MailOauth2Provider.java | 31 ++ .../settings/AdminSettingsServiceImpl.java | 27 +- pom.xml | 6 + ui-ngx/src/app/core/http/admin.service.ts | 13 + .../pages/admin/mail-server.component.html | 377 ++++++++++++---- .../pages/admin/mail-server.component.scss | 89 ++++ .../home/pages/admin/mail-server.component.ts | 404 +++++++++++++++--- .../src/app/shared/models/settings.models.ts | 42 +- .../assets/locale/locale.constant-en_US.json | 24 +- 22 files changed, 1448 insertions(+), 223 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java create mode 100644 application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java create mode 100644 application/src/main/java/org/thingsboard/server/service/mail/RefreshTokenExpCheckService.java create mode 100644 application/src/main/java/org/thingsboard/server/service/mail/TbMailConfigTemplateService.java create mode 100644 application/src/main/java/org/thingsboard/server/service/mail/TbMailContextComponent.java create mode 100644 application/src/main/java/org/thingsboard/server/service/mail/TbMailSender.java create mode 100644 application/src/main/resources/templates/mail_config_templates.json create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/mail/MailOauth2Provider.java diff --git a/application/pom.xml b/application/pom.xml index 8e7c3cd524..98b73133b6 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -354,6 +354,10 @@ com.slack.api slack-api-client + + com.google.oauth-client + google-oauth-client + diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java index a418dc268b..793670f0ab 100644 --- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java @@ -77,6 +77,8 @@ public class ThingsboardSecurityConfiguration { protected static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/assets/**", "/static/**", "/api/noauth/**", "/webjars/**", "/api/license/**"}; public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**"; + public static final String MAIL_OAUTH2_PROCESSING_ENTRY_POINT = "/api/admin/mail/oauth2/code"; + @Autowired private ThingsboardErrorResponseHandler restAccessDeniedHandler; @@ -134,7 +136,7 @@ public class ThingsboardSecurityConfiguration { protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter() throws Exception { List pathsToSkip = new ArrayList<>(Arrays.asList(NON_TOKEN_BASED_AUTH_ENTRY_POINTS)); pathsToSkip.addAll(Arrays.asList(WS_TOKEN_BASED_AUTH_ENTRY_POINT, TOKEN_REFRESH_ENTRY_POINT, FORM_BASED_LOGIN_ENTRY_POINT, - PUBLIC_LOGIN_ENTRY_POINT, DEVICE_API_ENTRY_POINT, WEBJARS_ENTRY_POINT)); + PUBLIC_LOGIN_ENTRY_POINT, DEVICE_API_ENTRY_POINT, WEBJARS_ENTRY_POINT, MAIL_OAUTH2_PROCESSING_ENTRY_POINT)); SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, TOKEN_BASED_AUTH_ENTRY_POINT); JwtTokenAuthenticationProcessingFilter filter = new JwtTokenAuthenticationProcessingFilter(failureHandler, jwtHeaderTokenExtractor, matcher); @@ -201,6 +203,7 @@ public class ThingsboardSecurityConfiguration { .antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point .antMatchers(PUBLIC_LOGIN_ENTRY_POINT).permitAll() // Public login end-point .antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point + .antMatchers(MAIL_OAUTH2_PROCESSING_ENTRY_POINT).permitAll() // Mail oauth2 code processing url .antMatchers(NON_TOKEN_BASED_AUTH_ENTRY_POINTS).permitAll() // static resources, user activation and password reset end-points .and() .authorizeRequests() diff --git a/application/src/main/java/org/thingsboard/server/controller/AdminController.java b/application/src/main/java/org/thingsboard/server/controller/AdminController.java index 5cf97a7cda..4019efe8ee 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java @@ -15,13 +15,24 @@ */ package org.thingsboard.server.controller; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl; +import com.google.api.client.auth.oauth2.AuthorizationCodeTokenRequest; +import com.google.api.client.auth.oauth2.ClientParametersAuthentication; +import com.google.api.client.auth.oauth2.TokenResponse; +import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.gson.GsonFactory; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -32,18 +43,25 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.SmsService; import org.thingsboard.server.common.data.AdminSettings; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.FeaturesInfo; import org.thingsboard.server.common.data.FeaturesInfo; import org.thingsboard.server.common.data.SystemInfo; import org.thingsboard.server.common.data.UpdateMessage; +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.security.model.JwtPair; import org.thingsboard.server.common.data.security.model.JwtSettings; @@ -56,6 +74,7 @@ import org.thingsboard.server.common.data.sync.vc.VcUtils; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.auth.oauth2.CookieUtils; import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; @@ -67,15 +86,29 @@ import org.thingsboard.server.service.sync.vc.autocommit.TbAutoCommitSettingsSer import org.thingsboard.server.service.system.SystemInfoService; import org.thingsboard.server.service.update.UpdateService; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +import static org.thingsboard.server.controller.ControllerConstants.*; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @RestController @TbCoreComponent +@Slf4j @RequestMapping("/api/admin") @RequiredArgsConstructor public class AdminController extends BaseController { + private static final String PREV_URI_PATH_PARAMETER = "prevUri"; + private static final String PREV_URI_COOKIE_NAME = "prev_uri"; + private static final String STATE_COOKIE_NAME = "state"; + private static final String MAIL_SETTINGS_KEY = "mail"; + private final MailService mailService; private final SmsService smsService; private final AdminSettingsService adminSettingsService; @@ -102,6 +135,7 @@ public class AdminController extends BaseController { AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key), "No Administration settings found for key: " + key); if (adminSettings.getKey().equals("mail")) { ((ObjectNode) adminSettings.getJsonValue()).remove("password"); + ((ObjectNode) adminSettings.getJsonValue()).remove("refreshToken"); } return adminSettings; } @@ -122,6 +156,7 @@ public class AdminController extends BaseController { if (adminSettings.getKey().equals("mail")) { mailService.updateMailConfiguration(); ((ObjectNode) adminSettings.getJsonValue()).remove("password"); + ((ObjectNode) adminSettings.getJsonValue()).remove("refreshToken"); } else if (adminSettings.getKey().equals("sms")) { smsService.updateSmsConfiguration(); } @@ -188,9 +223,20 @@ public class AdminController extends BaseController { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); adminSettings = checkNotNull(adminSettings); if (adminSettings.getKey().equals("mail")) { - if (!adminSettings.getJsonValue().has("password")) { + if (adminSettings.getJsonValue().has("enableOauth2") && adminSettings.getJsonValue().get("enableOauth2").asBoolean()){ AdminSettings mailSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail")); - ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText()); + JsonNode refreshToken = mailSettings.getJsonValue().get("refreshToken"); + if (refreshToken == null) { + throw new ThingsboardException("Refresh token was not generated. Please, generate refresh token.", ThingsboardErrorCode.GENERAL); + } + ObjectNode settings = (ObjectNode) adminSettings.getJsonValue(); + settings.put("refreshToken", refreshToken.asText()); + } + else { + if (!adminSettings.getJsonValue().has("password")) { + AdminSettings mailSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail")); + ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText()); + } } String email = getCurrentUser().getEmail(); mailService.sendTestMail(adminSettings.getJsonValue(), email); @@ -362,4 +408,84 @@ public class AdminController extends BaseController { return systemInfoService.getFeaturesInfo(); } + @ApiOperation(value = "Get OAuth2 log in processing URL (getMailProcessingUrl)", notes = "Returns the URL enclosed in " + + "double quotes. After successful authentication with OAuth2 provider and user consent for requested scope, it makes a redirect to this path so that the platform can do " + + "further log in processing and generating access tokens. " + SYSTEM_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") + @RequestMapping(value = "/mail/oauth2/loginProcessingUrl", method = RequestMethod.GET) + @ResponseBody + public String getMailProcessingUrl() throws ThingsboardException { + accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); + return "\"/api/admin/mail/oauth2/code\""; + } + + @ApiOperation(value = "Redirect user to mail provider login page. ", notes = "After user logged in and provided access" + + "provider sends authorization code to specified redirect uri.)" ) + @PreAuthorize("hasAuthority('SYS_ADMIN')") + @RequestMapping(value = "/mail/oauth2/authorize", method = RequestMethod.GET, produces = "application/text") + public String getAuthorizationUrl(HttpServletRequest request, HttpServletResponse response) throws ThingsboardException { + String state = StringUtils.generateSafeToken(); + if (request.getParameter(PREV_URI_PATH_PARAMETER) != null) { + CookieUtils.addCookie(response, PREV_URI_COOKIE_NAME, request.getParameter(PREV_URI_PATH_PARAMETER), 180); + } + CookieUtils.addCookie(response, STATE_COOKIE_NAME, state, 180); + + accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); + AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, MAIL_SETTINGS_KEY), "No Administration mail settings found"); + JsonNode jsonValue = adminSettings.getJsonValue(); + + String clientId = checkNotNull(jsonValue.get("clientId"), "No clientId was configured").asText(); + String authUri = checkNotNull(jsonValue.get("authUri"), "No authorization uri was configured").asText(); + String redirectUri = checkNotNull(jsonValue.get("redirectUri"), "No Redirect uri was configured").asText(); + List scope = JacksonUtil.convertValue(checkNotNull(jsonValue.get("scope"), "No scope was configured"), new TypeReference<>() { + }); + + return "\"" + new AuthorizationCodeRequestUrl(authUri, clientId) + .setScopes(scope) + .setState(state) + .setRedirectUri(redirectUri) + .build() + "\""; + } + + @RequestMapping(value = "/mail/oauth2/code", params = {"code", "state"}, method = RequestMethod.GET) + public void codeProcessingUrl( + @RequestParam(value = "code") String code, @RequestParam(value = "state") String state, + HttpServletRequest request, HttpServletResponse response) throws ThingsboardException, IOException { + Optional prevUrlOpt = CookieUtils.getCookie(request, PREV_URI_COOKIE_NAME); + Optional cookieState = CookieUtils.getCookie(request, STATE_COOKIE_NAME); + + String baseUrl = this.systemSecurityService.getBaseUrl(TenantId.SYS_TENANT_ID, new CustomerId(EntityId.NULL_UUID), request); + String prevUri = baseUrl + (prevUrlOpt.isPresent() ? prevUrlOpt.get().getValue(): "/settings/outgoing-mail"); + + if (cookieState.isEmpty() || !cookieState.get().getValue().equals(state)) { + CookieUtils.deleteCookie(request, response, STATE_COOKIE_NAME); + throw new ThingsboardException("Refresh token was not generated, invalid state param", ThingsboardErrorCode.BAD_REQUEST_PARAMS); + } + CookieUtils.deleteCookie(request, response, STATE_COOKIE_NAME); + CookieUtils.deleteCookie(request, response, PREV_URI_COOKIE_NAME); + + AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, MAIL_SETTINGS_KEY), "No Administration mail settings found"); + JsonNode jsonValue = adminSettings.getJsonValue(); + + String clientId = checkNotNull(jsonValue.get("clientId"), "No clientId was configured").asText(); + String clientSecret = checkNotNull(jsonValue.get("clientSecret"), "No client secret was configured").asText(); + String clientRedirectUri = checkNotNull(jsonValue.get("redirectUri"), "No Redirect uri was configured").asText(); + String tokenUri = checkNotNull(jsonValue.get("tokenUri"), "No authorization uri was configured").asText(); + + TokenResponse tokenResponse; + try { + tokenResponse = new AuthorizationCodeTokenRequest(new NetHttpTransport(), new GsonFactory(), new GenericUrl(tokenUri), code) + .setRedirectUri(clientRedirectUri) + .setClientAuthentication(new ClientParametersAuthentication(clientId, clientSecret)) + .execute(); + } catch (IOException e) { + log.warn("Unable to retrieve refresh token: {}", e.getMessage()); + throw new ThingsboardException("Error while requesting access token: " + e.getMessage(), ThingsboardErrorCode.GENERAL); + } + ((ObjectNode)jsonValue).put("refreshToken", tokenResponse.getRefreshToken()); + ((ObjectNode)jsonValue).put("tokenGenerated", true); + + adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings); + response.sendRedirect(prevUri); + } } diff --git a/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java new file mode 100644 index 0000000000..fc13edd3d7 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java @@ -0,0 +1,82 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.controller; + +import com.fasterxml.jackson.databind.JsonNode; +import com.nimbusds.jose.shaded.json.JSONObject; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.CharEncoding; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.ResourceType; +import org.thingsboard.server.common.data.TbResource; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.settings.AdminSettingsService; +import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.mail.TbMailConfigTemplateService; +import org.thingsboard.server.service.security.permission.Operation; +import org.thingsboard.server.service.security.permission.Resource; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Base64; + +import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; + +@RestController +@TbCoreComponent +@RequiredArgsConstructor +@RequestMapping("/api/mail/config/template") +@Slf4j +public class MailConfigTemplateController extends BaseController { + private static final String MAIL_CONFIG_TEMPLATE_ID = "mailConfigTemplateId"; + private static final String MAIL_CONFIG_TEMPLATE_DEFINITION = "Mail configuration template is set of default smtp settings for mail server that specific provider supports"; + + private final TbMailConfigTemplateService mailConfigTemplateService; + + @ApiOperation(value = "Get the list of all OAuth2 client registration templates (getClientRegistrationTemplates)" + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, + notes = MAIL_CONFIG_TEMPLATE_DEFINITION) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(method = RequestMethod.GET, produces = "application/json") + @ResponseBody + public JsonNode getClientRegistrationTemplates() throws ThingsboardException, IOException { + accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); + return mailConfigTemplateService.findAllMailConfigTemplates(); + } + +} diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java index f3fd18141a..1c6af41360 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.mail; import com.fasterxml.jackson.databind.JsonNode; + import freemarker.template.Configuration; import freemarker.template.Template; import lombok.extern.slf4j.Slf4j; @@ -53,7 +54,6 @@ import java.io.ByteArrayInputStream; import java.util.HashMap; import java.util.Locale; import java.util.Map; -import java.util.Properties; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -61,7 +61,6 @@ import java.util.concurrent.TimeoutException; @Slf4j public class DefaultMailService implements MailService { - public static final String MAIL_PROP = "mail."; public static final String TARGET_EMAIL = "targetEmail"; public static final String UTF_8 = "UTF-8"; @@ -82,7 +81,10 @@ public class DefaultMailService implements MailService { @Autowired private PasswordResetExecutorService passwordResetExecutorService; - private JavaMailSenderImpl mailSender; + @Autowired + private TbMailContextComponent tbMailContextComponent; + + private TbMailSender mailSender; private String mailFrom; @@ -105,7 +107,7 @@ public class DefaultMailService implements MailService { AdminSettings settings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); if (settings != null) { JsonNode jsonConfig = settings.getJsonValue(); - mailSender = createMailSender(jsonConfig); + mailSender = new TbMailSender(tbMailContextComponent, jsonConfig); mailFrom = jsonConfig.get("mailFrom").asText(); timeout = jsonConfig.get("timeout").asLong(DEFAULT_TIMEOUT); } else { @@ -113,65 +115,6 @@ public class DefaultMailService implements MailService { } } - private JavaMailSenderImpl createMailSender(JsonNode jsonConfig) { - JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); - mailSender.setHost(jsonConfig.get("smtpHost").asText()); - mailSender.setPort(parsePort(jsonConfig.get("smtpPort").asText())); - mailSender.setUsername(jsonConfig.get("username").asText()); - mailSender.setPassword(jsonConfig.get("password").asText()); - mailSender.setJavaMailProperties(createJavaMailProperties(jsonConfig)); - return mailSender; - } - - private Properties createJavaMailProperties(JsonNode jsonConfig) { - Properties javaMailProperties = new Properties(); - String protocol = jsonConfig.get("smtpProtocol").asText(); - javaMailProperties.put("mail.transport.protocol", protocol); - javaMailProperties.put(MAIL_PROP + protocol + ".host", jsonConfig.get("smtpHost").asText()); - javaMailProperties.put(MAIL_PROP + protocol + ".port", jsonConfig.get("smtpPort").asText()); - javaMailProperties.put(MAIL_PROP + protocol + ".timeout", jsonConfig.get("timeout").asText()); - javaMailProperties.put(MAIL_PROP + protocol + ".auth", String.valueOf(StringUtils.isNotEmpty(jsonConfig.get("username").asText()))); - boolean enableTls = false; - if (jsonConfig.has("enableTls")) { - if (jsonConfig.get("enableTls").isBoolean() && jsonConfig.get("enableTls").booleanValue()) { - enableTls = true; - } else if (jsonConfig.get("enableTls").isTextual()) { - enableTls = "true".equalsIgnoreCase(jsonConfig.get("enableTls").asText()); - } - } - javaMailProperties.put(MAIL_PROP + protocol + ".starttls.enable", enableTls); - if (enableTls && jsonConfig.has("tlsVersion") && !jsonConfig.get("tlsVersion").isNull()) { - String tlsVersion = jsonConfig.get("tlsVersion").asText(); - if (StringUtils.isNoneEmpty(tlsVersion)) { - javaMailProperties.put(MAIL_PROP + protocol + ".ssl.protocols", tlsVersion); - } - } - - boolean enableProxy = jsonConfig.has("enableProxy") && jsonConfig.get("enableProxy").asBoolean(); - - if (enableProxy) { - javaMailProperties.put(MAIL_PROP + protocol + ".proxy.host", jsonConfig.get("proxyHost").asText()); - javaMailProperties.put(MAIL_PROP + protocol + ".proxy.port", jsonConfig.get("proxyPort").asText()); - String proxyUser = jsonConfig.get("proxyUser").asText(); - if (StringUtils.isNoneEmpty(proxyUser)) { - javaMailProperties.put(MAIL_PROP + protocol + ".proxy.user", proxyUser); - } - String proxyPassword = jsonConfig.get("proxyPassword").asText(); - if (StringUtils.isNoneEmpty(proxyPassword)) { - javaMailProperties.put(MAIL_PROP + protocol + ".proxy.password", proxyPassword); - } - } - return javaMailProperties; - } - - private int parsePort(String strPort) { - try { - return Integer.valueOf(strPort); - } catch (NumberFormatException e) { - throw new IncorrectParameterException(String.format("Invalid smtp port value: %s", strPort)); - } - } - @Override public void sendEmail(TenantId tenantId, String email, String subject, String message) throws ThingsboardException { sendMail(mailSender, mailFrom, email, subject, message, timeout); @@ -179,7 +122,7 @@ public class DefaultMailService implements MailService { @Override public void sendTestMail(JsonNode jsonConfig, String email) throws ThingsboardException { - JavaMailSenderImpl testMailSender = createMailSender(jsonConfig); + TbMailSender testMailSender = new TbMailSender(tbMailContextComponent, jsonConfig); String mailFrom = jsonConfig.get("mailFrom").asText(); String subject = messages.getMessage("test.message.subject", null, Locale.US); long timeout = jsonConfig.get("timeout").asLong(DEFAULT_TIMEOUT); diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java new file mode 100644 index 0000000000..3d4cb261c7 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java @@ -0,0 +1,19 @@ +package org.thingsboard.server.service.mail; + +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import org.thingsboard.common.util.JacksonUtil; + +import java.io.IOException; + +@Service +@Slf4j +public class DefaultTbMailConfigTemplateService implements TbMailConfigTemplateService { + + @Override + public JsonNode findAllMailConfigTemplates() throws IOException { + return JacksonUtil.toJsonNode(new ClassPathResource("/templates/mail_config_templates.json").getFile()); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/mail/RefreshTokenExpCheckService.java b/application/src/main/java/org/thingsboard/server/service/mail/RefreshTokenExpCheckService.java new file mode 100644 index 0000000000..56f3c4c4c5 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/mail/RefreshTokenExpCheckService.java @@ -0,0 +1,75 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.mail; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.api.client.auth.oauth2.ClientParametersAuthentication; +import com.google.api.client.auth.oauth2.RefreshTokenRequest; +import com.google.api.client.auth.oauth2.TokenResponse; +import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.gson.GsonFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.AdminSettings; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.settings.AdminSettingsService; +import org.thingsboard.server.queue.util.TbCoreComponent; + +import java.io.IOException; +import java.time.Duration; +import java.time.Instant; + +import static org.thingsboard.server.common.data.mail.MailOauth2Provider.OFFICE_365; + +@TbCoreComponent +@Service +@Slf4j +@RequiredArgsConstructor +public class RefreshTokenExpCheckService { + public static final int AZURE_DEFAULT_REFRESH_TOKEN_LIFETIME_IN_DAYS = 90; + private final AdminSettingsService adminSettingsService; + + @Scheduled(initialDelayString = "#{T(org.apache.commons.lang3.RandomUtils).nextLong(0, ${mail.oauth2.refreshTokenCheckingInterval})}", fixedDelayString = "${mail.oauth2.refreshTokenCheckingInterval}") + public void check() throws IOException { + AdminSettings settings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); + if (settings != null && settings.getJsonValue().has("enableOauth2") && settings.getJsonValue().get("enableOauth2").asBoolean()) { + JsonNode jsonValue = settings.getJsonValue(); + if (OFFICE_365.name().equals(jsonValue.get("providerId").asText()) && jsonValue.has("refreshTokenExpires")) { + long expiresIn = jsonValue.get("refreshTokenExpires").longValue(); + if ((expiresIn - System.currentTimeMillis()) < 604800000L) { //less than 7 days + log.info("Trying to refresh refresh token."); + + String clientId = jsonValue.get("clientId").asText(); + String clientSecret = jsonValue.get("clientSecret").asText(); + String refreshToken = jsonValue.get("refreshToken").asText(); + String tokenUri = jsonValue.get("tokenUri").asText(); + + TokenResponse tokenResponse = new RefreshTokenRequest(new NetHttpTransport(), new GsonFactory(), + new GenericUrl(tokenUri), refreshToken) + .setClientAuthentication(new ClientParametersAuthentication(clientId, clientSecret)) + .execute(); + ((ObjectNode)jsonValue).put("refreshToken", tokenResponse.getRefreshToken()); + ((ObjectNode)jsonValue).put("refreshTokenExpires", Instant.now().plus(Duration.ofDays(AZURE_DEFAULT_REFRESH_TOKEN_LIFETIME_IN_DAYS)).toEpochMilli()); + adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, settings); + } + } + } + } +} \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/mail/TbMailConfigTemplateService.java b/application/src/main/java/org/thingsboard/server/service/mail/TbMailConfigTemplateService.java new file mode 100644 index 0000000000..2475fe7513 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/mail/TbMailConfigTemplateService.java @@ -0,0 +1,9 @@ +package org.thingsboard.server.service.mail; + +import com.fasterxml.jackson.databind.JsonNode; + +import java.io.IOException; + +public interface TbMailConfigTemplateService { + JsonNode findAllMailConfigTemplates() throws IOException; +} diff --git a/application/src/main/java/org/thingsboard/server/service/mail/TbMailContextComponent.java b/application/src/main/java/org/thingsboard/server/service/mail/TbMailContextComponent.java new file mode 100644 index 0000000000..dce6c10b7e --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/mail/TbMailContextComponent.java @@ -0,0 +1,32 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.mail; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; +import org.thingsboard.server.dao.settings.AdminSettingsService; +import org.thingsboard.server.queue.util.TbCoreComponent; + +@Component +@Data +@Lazy +public class TbMailContextComponent { + + @Autowired + private AdminSettingsService adminSettingsService; +} \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/mail/TbMailSender.java b/application/src/main/java/org/thingsboard/server/service/mail/TbMailSender.java new file mode 100644 index 0000000000..0a9b173247 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/mail/TbMailSender.java @@ -0,0 +1,168 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.service.mail; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.api.client.auth.oauth2.ClientParametersAuthentication; +import com.google.api.client.auth.oauth2.RefreshTokenRequest; +import com.google.api.client.auth.oauth2.TokenResponse; +import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.gson.GsonFactory; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.Nullable; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.thingsboard.server.common.data.AdminSettings; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.mail.MailOauth2Provider; +import org.thingsboard.server.dao.exception.IncorrectParameterException; + +import javax.mail.internet.MimeMessage; +import java.time.Duration; +import java.time.Instant; +import java.util.Properties; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import static org.thingsboard.server.service.mail.RefreshTokenExpCheckService.AZURE_DEFAULT_REFRESH_TOKEN_LIFETIME_IN_DAYS; + +@Slf4j +public class TbMailSender extends JavaMailSenderImpl { + + private static final String MAIL_PROP = "mail."; + private final TbMailContextComponent ctx; + private final Lock lock; + private final Boolean oauth2Enabled; + private volatile String accessToken; + private volatile long tokenExpires; + + public TbMailSender(TbMailContextComponent ctx, JsonNode jsonConfig) { + super(); + this.lock = new ReentrantLock(); + this.tokenExpires = 0L; + this.ctx = ctx; + this.oauth2Enabled = jsonConfig.has("enableOauth2") && jsonConfig.get("enableOauth2").asBoolean(); + + setHost(jsonConfig.get("smtpHost").asText()); + setPort(parsePort(jsonConfig.get("smtpPort").asText())); + setUsername(jsonConfig.get("username").asText()); + if (jsonConfig.has("password")) { + setPassword(jsonConfig.get("password").asText()); + } + setJavaMailProperties(createJavaMailProperties(jsonConfig)); + } + + @SneakyThrows + @Override + public void doSend(MimeMessage[] mimeMessages, @Nullable Object[] originalMessages) { + if (oauth2Enabled && (System.currentTimeMillis() > tokenExpires)){ + refreshAccessToken(); + setPassword(accessToken); + } + super.doSend(mimeMessages, originalMessages); + } + + private Properties createJavaMailProperties(JsonNode jsonConfig) { + Properties javaMailProperties = new Properties(); + String protocol = jsonConfig.get("smtpProtocol").asText(); + javaMailProperties.put("mail.transport.protocol", protocol); + javaMailProperties.put(MAIL_PROP + protocol + ".host", jsonConfig.get("smtpHost").asText()); + javaMailProperties.put(MAIL_PROP + protocol + ".port", jsonConfig.get("smtpPort").asText()); + javaMailProperties.put(MAIL_PROP + protocol + ".timeout", jsonConfig.get("timeout").asText()); + javaMailProperties.put(MAIL_PROP + protocol + ".auth", String.valueOf(StringUtils.isNotEmpty(jsonConfig.get("username").asText()))); + boolean enableTls = false; + if (jsonConfig.has("enableTls")) { + if (jsonConfig.get("enableTls").isBoolean() && jsonConfig.get("enableTls").booleanValue()) { + enableTls = true; + } else if (jsonConfig.get("enableTls").isTextual()) { + enableTls = "true".equalsIgnoreCase(jsonConfig.get("enableTls").asText()); + } + } + javaMailProperties.put(MAIL_PROP + protocol + ".starttls.enable", enableTls); + if (enableTls && jsonConfig.has("tlsVersion") && !jsonConfig.get("tlsVersion").isNull()) { + String tlsVersion = jsonConfig.get("tlsVersion").asText(); + if (StringUtils.isNoneEmpty(tlsVersion)) { + javaMailProperties.put(MAIL_PROP + protocol + ".ssl.protocols", tlsVersion); + } + } + + boolean enableProxy = jsonConfig.has("enableProxy") && jsonConfig.get("enableProxy").asBoolean(); + + if (enableProxy) { + javaMailProperties.put(MAIL_PROP + protocol + ".proxy.host", jsonConfig.get("proxyHost").asText()); + javaMailProperties.put(MAIL_PROP + protocol + ".proxy.port", jsonConfig.get("proxyPort").asText()); + String proxyUser = jsonConfig.get("proxyUser").asText(); + if (StringUtils.isNoneEmpty(proxyUser)) { + javaMailProperties.put(MAIL_PROP + protocol + ".proxy.user", proxyUser); + } + String proxyPassword = jsonConfig.get("proxyPassword").asText(); + if (StringUtils.isNoneEmpty(proxyPassword)) { + javaMailProperties.put(MAIL_PROP + protocol + ".proxy.password", proxyPassword); + } + } + + if (oauth2Enabled) { + javaMailProperties.put(MAIL_PROP + protocol + ".auth.mechanisms", "XOAUTH2"); + } + return javaMailProperties; + } + + public void refreshAccessToken() throws ThingsboardException { + lock.lock(); + try { + if (System.currentTimeMillis() > tokenExpires) { + AdminSettings settings = ctx.getAdminSettingsService().findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail"); + JsonNode jsonValue = settings.getJsonValue(); + + String clientId = jsonValue.get("clientId").asText(); + String clientSecret = jsonValue.get("clientSecret").asText(); + String refreshToken = jsonValue.get("refreshToken").asText(); + String tokenUri = jsonValue.get("tokenUri").asText(); + String providerId = jsonValue.get("providerId").asText(); + + TokenResponse tokenResponse = new RefreshTokenRequest(new NetHttpTransport(), new GsonFactory(), + new GenericUrl(tokenUri), refreshToken) + .setClientAuthentication(new ClientParametersAuthentication(clientId, clientSecret)) + .execute(); + if (MailOauth2Provider.OFFICE_365.name().equals(providerId)) { + ((ObjectNode)jsonValue).put("refreshToken", tokenResponse.getRefreshToken()); + ((ObjectNode)jsonValue).put("refreshTokenExpires", Instant.now().plus(Duration.ofDays(AZURE_DEFAULT_REFRESH_TOKEN_LIFETIME_IN_DAYS)).toEpochMilli()); + ctx.getAdminSettingsService().saveAdminSettings(TenantId.SYS_TENANT_ID, settings); + } + accessToken = tokenResponse.getAccessToken(); + tokenExpires = System.currentTimeMillis() + (tokenResponse.getExpiresInSeconds().intValue() * 1000); + } + } catch (Exception e) { + log.warn("Unable to retrieve access token: {}", e.getMessage()); + throw new ThingsboardException("Error while retrieving access token: " + e.getMessage(), ThingsboardErrorCode.GENERAL); + } finally { + lock.unlock(); + } + } + + private int parsePort(String strPort) { + try { + return Integer.parseInt(strPort); + } catch (NumberFormatException e) { + throw new IncorrectParameterException(String.format("Invalid smtp port value: %s", strPort)); + } + } +} \ No newline at end of file diff --git a/application/src/main/resources/templates/mail_config_templates.json b/application/src/main/resources/templates/mail_config_templates.json new file mode 100644 index 0000000000..f287880a5e --- /dev/null +++ b/application/src/main/resources/templates/mail_config_templates.json @@ -0,0 +1,52 @@ +[ + { + "providerId": "SENDGRID", + "smtpProtocol": "SMTPS", + "smtpHost": "smtp.sendgrid.net", + "smtpPort": 465, + "timeout": 10000, + "enableTls": true, + "tlsVersion": "TLSv1.2", + "authorizationUri": null, + "accessTokenUri": null, + "scope": [ + "" + ], + "helpLink": null, + "name": "SendGrid" + }, + { + "providerId": "GOOGLE", + "smtpProtocol": "SMTPS", + "smtpHost": "smtp.gmail.com", + "smtpPort": 465, + "timeout": 10000, + "enableTls": true, + "tlsVersion": "TLSv1.2", + "authorizationUri": "https://accounts.google.com/o/oauth2/v2/auth?prompt=consent&access_type=offline", + "accessTokenUri": "https://oauth2.googleapis.com/token", + "scope": [ + "https://mail.google.com/" + ], + "helpLink": "https://support.google.com/googleapi/answer/6158849", + "name": "Google" + }, + { + "providerId": "OFFICE_365", + "smtpProtocol": "SMTP", + "smtpHost": "smtp.office365.com", + "smtpPort": 587, + "timeout": 10000, + "enableTls": true, + "tlsVersion": "TLSv1.2", + "authorizationUri": "https://login.microsoftonline.com/%s/oauth2/v2.0/authorize", + "accessTokenUri": "https://login.microsoftonline.com/%s/oauth2/v2.0/token", + "scope": [ + "https://outlook.office365.com/SMTP.Send", + "offline_access", + "openid" + ], + "helpLink": "https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth", + "name": "Office 365" + } +] \ No newline at end of file diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 3916d3e0be..d3d79458f3 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -135,6 +135,10 @@ security: path: "${SECURITY_JAVA_CACERTS_PATH:${java.home}/lib/security/cacerts}" password: "${SECURITY_JAVA_CACERTS_PASSWORD:changeit}" +mail: + oauth2: + refreshTokenCheckingInterval: "${REFRESH_TOKEN_EXPIRATION_CHECKING_INTERVAL:86400}" # Number of seconds (1 day). + # Usage statistics parameters usage: stats: diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java index 3f4aa11c1f..a7671f4327 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/StringUtils.java @@ -24,6 +24,9 @@ import java.util.Base64; import static org.apache.commons.lang3.StringUtils.repeat; public class StringUtils { + + private static final int DEFAULT_TOKEN_LENGTH = 8; + public static final SecureRandom RANDOM = new SecureRandom(); public static final String EMPTY = ""; @@ -205,4 +208,8 @@ public class StringUtils { return encoder.encodeToString(bytes); } + public static String generateSafeToken() { + return generateSafeToken(DEFAULT_TOKEN_LENGTH); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mail/MailOauth2Provider.java b/common/data/src/main/java/org/thingsboard/server/common/data/mail/MailOauth2Provider.java new file mode 100644 index 0000000000..c0cdb92500 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mail/MailOauth2Provider.java @@ -0,0 +1,31 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.mail; + +public enum MailOauth2Provider { + GOOGLE("Google"), OFFICE_365("Office 365"), SENDGRID("SendGrid"), CUSTOM("Custom"); + + public final String label; + + MailOauth2Provider(String label) { + this.label = label; + } + + @Override + public String toString() { + return label; + } +} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java index b6d6bbc0ad..6da6d96637 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.settings; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -58,10 +59,18 @@ public class AdminSettingsServiceImpl implements AdminSettingsService { public AdminSettings saveAdminSettings(TenantId tenantId, AdminSettings adminSettings) { log.trace("Executing saveAdminSettings [{}]", adminSettings); adminSettingsValidator.validate(adminSettings, data -> tenantId); - if (adminSettings.getKey().equals("mail") && !adminSettings.getJsonValue().has("password")) { + if (adminSettings.getKey().equals("mail")){ AdminSettings mailSettings = findAdminSettingsByKey(tenantId, "mail"); if (mailSettings != null) { - ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText()); + JsonNode newJsonValue = adminSettings.getJsonValue(); + JsonNode oldJsonValue = mailSettings.getJsonValue(); + if (!newJsonValue.has("password") && oldJsonValue.has("password")){ + ((ObjectNode) newJsonValue).put("password", oldJsonValue.get("password").asText()); + } + if (!newJsonValue.has("refreshToken") && oldJsonValue.has("refreshToken")){ + ((ObjectNode) newJsonValue).put("refreshToken", oldJsonValue.get("refreshToken").asText()); + } + dropTokenIfProviderInfoChanged(newJsonValue, oldJsonValue); } } if (adminSettings.getTenantId() == null) { @@ -82,4 +91,18 @@ public class AdminSettingsServiceImpl implements AdminSettingsService { adminSettingsDao.removeByTenantId(tenantId.getId()); } + private void dropTokenIfProviderInfoChanged(JsonNode newJsonValue, JsonNode oldJsonValue) { + if (newJsonValue.has("enableOauth2") && newJsonValue.get("enableOauth2").asBoolean()){ + if (!newJsonValue.get("providerId").equals(oldJsonValue.get("providerId")) || + !newJsonValue.get("clientId").equals(oldJsonValue.get("clientId")) || + !newJsonValue.get("clientSecret").equals(oldJsonValue.get("clientSecret")) || + !newJsonValue.get("redirectUri").equals(oldJsonValue.get("redirectUri")) || + (newJsonValue.has("providerTenantId") && !newJsonValue.get("providerTenantId").equals(oldJsonValue.get("providerTenantId")))){ + ((ObjectNode) newJsonValue).put("tokenGenerated", false); + ((ObjectNode) newJsonValue).remove("refreshToken"); + ((ObjectNode) newJsonValue).remove("refreshTokenExpires"); + } + } + } + } diff --git a/pom.xml b/pom.xml index f4c4970d7f..59d1eff5d3 100755 --- a/pom.xml +++ b/pom.xml @@ -151,6 +151,7 @@ 2.12.0 1.12.1 6.4.2 + 1.34.1 @@ -2017,6 +2018,11 @@ oshi-core ${oshi.version} + + com.google.oauth-client + google-oauth-client + ${google-oauth-client.version} + diff --git a/ui-ngx/src/app/core/http/admin.service.ts b/ui-ngx/src/app/core/http/admin.service.ts index cd83c3c8c9..d7126df824 100644 --- a/ui-ngx/src/app/core/http/admin.service.ts +++ b/ui-ngx/src/app/core/http/admin.service.ts @@ -21,6 +21,7 @@ import { HttpClient } from '@angular/common/http'; import { AdminSettings, AutoCommitSettings, + MailConfigTemplate, FeaturesInfo, JwtSettings, MailServerSettings, @@ -136,4 +137,16 @@ export class AdminService { public getFeaturesInfo(config?: RequestConfig): Observable { return this.http.get('/api/admin/featuresInfo', defaultHttpOptionsFromConfig(config)); } + + public getLoginProcessingUrl(config?: RequestConfig): Observable { + return this.http.get(`/api/admin/mail/oauth2/loginProcessingUrl`, defaultHttpOptionsFromConfig(config)); + } + + public generateAccessToken(config?: RequestConfig): Observable { + return this.http.get(`/api/admin/mail/oauth2/authorize`, defaultHttpOptionsFromConfig(config)); + } + + public getMailConfigTemplate(config?: RequestConfig): Observable> { + return this.http.get>('/api/mail/config/template', defaultHttpOptionsFromConfig(config)); + } } diff --git a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.html b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.html index 4524880098..2762e0d43a 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.html +++ b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.html @@ -37,111 +37,306 @@ {{ 'admin.mail-from-required' | translate }} + - admin.smtp-protocol - - - {{protocol.toUpperCase()}} - - - -
- - admin.smtp-host - - - {{ 'admin.smtp-host-required' | translate }} - - - - admin.smtp-port - - {{smtpPortInput.value?.length || 0}}/5 - - {{ 'admin.smtp-port-required' | translate }} - - - {{ 'admin.smtp-port-invalid' | translate }} - - -
- - admin.timeout-msec - - {{timeoutInput.value?.length || 0}}/6 - - {{ 'admin.timeout-required' | translate }} - - - {{ 'admin.timeout-invalid' | translate }} - - - - {{ 'admin.enable-tls' | translate }} - - - admin.tls-version - - - {{ tlsVersion }} + admin.oauth2.smtp-provider + + + {{ templates.get(provider)?.name || 'Custom' }} - - {{ 'admin.enable-proxy' | translate }} - -
-
- - admin.proxy-host - - - {{ 'admin.proxy-host-required' | translate }} - + + + + + admin.connection-settings + + + + + admin.smtp-protocol + + + {{protocol.toUpperCase()}} + + - - admin.proxy-port - - - {{ 'admin.proxy-port-required' | translate }} +
+ + admin.smtp-host + + + {{ 'admin.smtp-host-required' | translate }} + + + + admin.smtp-port + + {{smtpPortInput.value?.length || 0}}/5 + + {{ 'admin.smtp-port-required' | translate }} + + + {{ 'admin.smtp-port-invalid' | translate }} + + +
+ + admin.timeout-msec + + {{timeoutInput.value?.length || 0}}/6 + + {{ 'admin.timeout-required' | translate }} - - {{ 'admin.proxy-port-range' | translate }} + + {{ 'admin.timeout-invalid' | translate }} -
- - admin.proxy-user - - + + {{ 'admin.enable-tls' | translate }} + + + admin.tls-version + + + {{ tlsVersion }} + + + + + {{ 'admin.enable-proxy' | translate }} + +
+
+ + admin.proxy-host + + + {{ 'admin.proxy-host-required' | translate }} + + + + admin.proxy-port + + + {{ 'admin.proxy-port-required' | translate }} + + + {{ 'admin.proxy-port-range' | translate }} + + +
+
+ + admin.proxy-user + + + + admin.proxy-password + + + +
+
+ + + +
+ admin.oauth2.authentication - admin.proxy-password - - + common.username + -
- - common.username - - - - {{ 'admin.change-password' | translate }} - - - common.password - - - +
+ + {{ 'admin.oauth2.basic' | translate }} + {{ 'admin.oauth2.oauth2' | translate }} + +
+
+
+
+
+ + {{ 'admin.change-password' | translate }} + + + common.password + + + +
+
+
+ + admin.oauth2.client-id + + + {{ 'admin.oauth2.client-id-required' | translate }} + + + {{ 'admin.oauth2.client-id-max-length' | translate }} + + + + + admin.oauth2.client-secret + + + {{ 'admin.oauth2.client-secret-required' | translate }} + + + {{ 'admin.oauth2.client-secret-max-length' | translate }} + + +
+ + + admin.oauth2.microsoft-tenant-id + + + {{ 'admin.oauth2.microsoft-tenant-id-required' | translate }} + + + + + + tenant-profile.advanced-settings + + + +
+ + admin.oauth2.authorization-uri + + + + {{ 'admin.oauth2.access-token-uri-required' | translate }} + + + {{ 'admin.oauth2.uri-pattern-error' | translate }} + + + + + admin.oauth2.token-uri + + + + {{ 'admin.oauth2.access-token-uri-required' | translate }} + + + {{ 'admin.oauth2.uri-pattern-error' | translate }} + + +
+ + admin.oauth2.scope + + + {{scope}} + cancel + + + + + {{ 'admin.oauth2.scope-required' | translate }} + + +
+
+ +
+ admin.oauth2.redirect-uri +
+
+
+ + admin.oauth2.protocol + + + {{ domainSchemaTranslations.get(protocol) | translate | uppercase }} + + + + + admin.domain-name + + + {{ 'admin.error-verification-url' | translate }} + + + {{ 'admin.domain-name-max-length' | translate }} + + +
+ + {{ 'admin.domain-name-unique' | translate }} + +
+ +
+ + admin.oauth2.redirect-uri-template + + + + +
+
+
+
+
+
+ admin.oauth2.access-token-status + + {{ accessTokenStatus }} + +
+ +
+
-
diff --git a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.scss b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.scss index 66df772d2d..cd6c18af9e 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.scss +++ b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.scss @@ -13,6 +13,95 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@import "../../../../../theme"; + :host { + .fields-group { + padding: 0 8px 8px; + margin: 10px 0; + border: 1px groove rgba(0, 0, 0, .25); + border-radius: 4px; + legend { + margin-bottom: 8px; + color: rgba(0, 0, 0, .7); + width: fit-content; + } + } + + .token-status { + font: 400 14px / 16px Roboto, "Helvetica Neue", sans-serif; + color: rgba(0,0,0, 0.6); + letter-spacing: 0.25px; + padding: 8px 0; + } + + ::ng-deep{ + .mat-expansion-panel { + .mat-expansion-panel-header { + height: 48px; + padding: 0 12px; + &.mat-expanded { + height: 48px; + } + } + .mat-expansion-panel-body { + padding: 0 12px; + } + &.configuration-panel { + border: 1px solid rgba(0, 0, 0, 0.2); + } + } + .mat-button-toggle-group.tb-notification-unread-toggle-group { + &.mat-button-toggle-group-appearance-standard { + border: none; + border-radius: 14px; + + .mat-button-toggle + .mat-button-toggle { + border-left: none; + } + } + + .mat-button-toggle { + background: rgba(0, 0, 0, 0.06); + height: 28px; + align-items: center; + display: flex; + + .mat-button-toggle-ripple { + top: 2px; + left: 2px; + right: 2px; + bottom: 2px; + border-radius: 12px; + } + } + + .mat-button-toggle-button { + color: #959595; + } + + .mat-button-toggle-focus-overlay { + border-radius: 14px; + margin: 2px; + } + + .mat-button-toggle-checked .mat-button-toggle-button { + background-color: $tb-primary-color; + color: #fff; + border-radius: 14px; + margin-left: 2px; + margin-right: 2px; + } + + .mat-button-toggle-appearance-standard .mat-button-toggle-label-content { + line-height: 24px; + font-size: 16px; + font-weight: 500; + } + .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay { + opacity: .01; + } + } + } } diff --git a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.ts b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.ts index 7833c745f4..6815c81e31 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.ts @@ -14,20 +14,32 @@ /// limitations under the License. /// -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { PageComponent } from '@shared/components/page.component'; -import { Router } from '@angular/router'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; -import { AdminSettings, MailServerSettings, smtpPortPattern } from '@shared/models/settings.models'; +import { FormBuilder, FormGroup, UntypedFormArray, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { + AdminSettings, + MailConfigTemplate, + MailServerOauth2Provider, + MailServerSettings, + smtpPortPattern, + SmtpProtocol +} from '@shared/models/settings.models'; import { AdminService } from '@core/http/admin.service'; import { ActionNotificationShow } from '@core/notification/notification.actions'; import { TranslateService } from '@ngx-translate/core'; import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard'; -import { isDefinedAndNotNull, isString } from '@core/utils'; -import { Subject } from 'rxjs'; +import { isDefined, isDefinedAndNotNull, isString } from '@core/utils'; +import { forkJoin, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; +import { DomainSchema, domainSchemaTranslations, } from '@shared/models/oauth2.models'; +import { WINDOW } from '@core/services/window.service'; +import { AuthService } from '@core/auth/auth.service'; +import { COMMA, ENTER } from '@angular/cdk/keycodes'; +import { MatChipInputEvent } from '@angular/material/chips'; @Component({ selector: 'tb-mail-server', @@ -35,40 +47,138 @@ import { takeUntil } from 'rxjs/operators'; styleUrls: ['./mail-server.component.scss', './settings-card.scss'] }) export class MailServerComponent extends PageComponent implements OnInit, OnDestroy, HasConfirmForm { - - mailSettings: UntypedFormGroup; adminSettings: AdminSettings; - smtpProtocols = ['smtp', 'smtps']; + smtpProtocols = Object.values(SmtpProtocol); showChangePassword = false; + protocols = Object.values(DomainSchema).filter(value => value !== DomainSchema.MIXED); + domainSchemaTranslations = domainSchemaTranslations; + + mailServerOauth2Provider = MailServerOauth2Provider; + tlsVersions = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3']; + helpLink: string; + + templates = new Map(); + + templateProvider = ['CUSTOM']; + + readonly separatorKeysCodes: number[] = [ENTER, COMMA]; + private destroy$ = new Subject(); + private DOMAIN_AND_PORT_REGEXP = /^(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?$/; + private URL_REGEXP = /^[A-Za-z][A-Za-z\d.+-]*:\/*(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?(?:\/[\w#!:.,?+=&%@\-/]*)?$/; + private loginProcessingUrl: string; + + mailSettings = this.fb.group({ + mailFrom: ['', [Validators.required]], + smtpProtocol: [SmtpProtocol.SMTP], + smtpHost: ['localhost', [Validators.required]], + smtpPort: [25, [Validators.required, + Validators.pattern(smtpPortPattern), + Validators.maxLength(5)]], + timeout: [10000, [Validators.required, + Validators.pattern(/^[0-9]{1,6}$/), + Validators.maxLength(6)]], + enableTls: [false], + tlsVersion: [{ value: null, disabled: true }], + enableProxy: [false], + proxyHost: [{ value: '', disabled: true }, [Validators.required]], + proxyPort: [{ value: null, disabled: true }, [Validators.required, Validators.min(1), Validators.max(65535)]], + proxyUser: [{ value: '', disabled: true }], + proxyPassword: [{ value: '', disabled: true }], + username: [''], + changePassword: [false], + password: [''], + enableOauth2: [false], + providerId: ['CUSTOM', [Validators.required]], + clientId: [{ value:'', disabled: true }, [Validators.required, Validators.maxLength(255)]], + clientSecret: [{ value:'', disabled: true }, [Validators.required, Validators.maxLength(2048)]], + providerTenantId: [{value: '', disabled: true}, [Validators.required]], + authUri: [{value: '', disabled: true}, [Validators.required, Validators.pattern(this.URL_REGEXP)]], + tokenUri: [{value: '', disabled: true}, [Validators.required, Validators.pattern(this.URL_REGEXP)]], + scope: [], + redirectUri: [{ value:'', disabled: true}] + }); + + private defaultConfiguration = { + providerId: 'CUSTOM', + smtpProtocol: SmtpProtocol.SMTP, + smtpHost: '', + smtpPort: null, + timeout: null, + enableTls: false, + tlsVersion: null, + enableProxy: false, + proxyHost: '', + proxyPort: null, + proxyUser: '', + proxyPassword: '', + enableOauth2: false, + clientId: '', + clientSecret: '', + providerTenantId: '', + authUri: '', + tokenUri: '', + scope: [], + redirectUri: '' + }; + + domainForm = this.fb.group({ + name: [this.window.location.hostname, [ + Validators.required, Validators.maxLength(255), + Validators.pattern(this.DOMAIN_AND_PORT_REGEXP)] + ], + scheme: [DomainSchema.HTTPS, Validators.required] + }); constructor(protected store: Store, private router: Router, + private route: ActivatedRoute, private adminService: AdminService, + private authService: AuthService, private translate: TranslateService, - public fb: UntypedFormBuilder) { + public fb: FormBuilder, + @Inject(WINDOW) private window: Window) { super(store); } ngOnInit() { - this.buildMailServerSettingsForm(); - this.adminService.getAdminSettings('mail').subscribe( - (adminSettings) => { - this.adminSettings = adminSettings; - if (this.adminSettings.jsonValue && isString(this.adminSettings.jsonValue.enableTls)) { - this.adminSettings.jsonValue.enableTls = (this.adminSettings.jsonValue.enableTls as any) === 'true'; - } - this.showChangePassword = - isDefinedAndNotNull(this.adminSettings.jsonValue.showChangePassword) ? this.adminSettings.jsonValue.showChangePassword : true ; - delete this.adminSettings.jsonValue.showChangePassword; - this.mailSettings.reset(this.adminSettings.jsonValue); - this.enableMailPassword(!this.showChangePassword); - this.enableProxyChanged(); + this.mailServerSettingsForm(); + this.domainFormConfiguration(); + + forkJoin([ + this.adminService.getLoginProcessingUrl(), + this.adminService.getMailConfigTemplate(), + this.adminService.getAdminSettings('mail') + ]).subscribe(([loginProcessingUrl, mailConfigTemplate, adminSettings]) => { + this.loginProcessingUrl = loginProcessingUrl; + this.initTemplates(mailConfigTemplate); + this.adminSettings = adminSettings; + if (this.adminSettings.jsonValue && isString(this.adminSettings.jsonValue.enableTls)) { + this.adminSettings.jsonValue.enableTls = (this.adminSettings.jsonValue.enableTls as any) === 'true'; } - ); + this.showChangePassword = isDefinedAndNotNull(this.adminSettings.jsonValue.showChangePassword) + ? this.adminSettings.jsonValue.showChangePassword : true; + delete this.adminSettings.jsonValue.showChangePassword; + if (!this.adminSettings.jsonValue.providerId) { + this.adminSettings.jsonValue.providerId = 'CUSTOM'; + } + this.mailSettings.reset(this.adminSettings.jsonValue, {emitEvent: false}); + this.enableMailPassword(!this.showChangePassword); + this.enableProxyChanged(); + this.enableTls(this.adminSettings.jsonValue.enableTls); + this.helpLink = this.templates.get(this.adminSettings.jsonValue.providerId)?.helpLink || null; + if (this.adminSettings.jsonValue.enableOauth2) { + this.enableOauth2(!!this.adminSettings.jsonValue.enableOauth2); + this.enableProviderTenantIdChanged(this.adminSettings.jsonValue.providerId); + this.parseUrl(this.adminSettings.jsonValue.redirectUri); + this.mailSettings.get('redirectUri').patchValue(this.adminSettings.jsonValue.redirectUri, {emitEvent: false}); + } else { + this.mailSettings.get('enableOauth2').patchValue(false, {emitEvent: false}); + } + }); } ngOnDestroy() { @@ -77,56 +187,153 @@ export class MailServerComponent extends PageComponent implements OnInit, OnDest super.ngOnDestroy(); } - buildMailServerSettingsForm() { - this.mailSettings = this.fb.group({ - mailFrom: ['', [Validators.required]], - smtpProtocol: ['smtp'], - smtpHost: ['localhost', [Validators.required]], - smtpPort: ['25', [Validators.required, - Validators.pattern(smtpPortPattern), - Validators.maxLength(5)]], - timeout: ['10000', [Validators.required, - Validators.pattern(/^[0-9]{1,6}$/), - Validators.maxLength(6)]], - enableTls: [false], - tlsVersion: [], - enableProxy: [false, []], - proxyHost: ['', [Validators.required]], - proxyPort: ['', [Validators.required, Validators.min(1), Validators.max(65535)]], - proxyUser: [''], - proxyPassword: [''], - username: [''], - changePassword: [false], - password: [''] + private initTemplates(templates): void { + templates.map(provider => { + delete provider.additionalInfo; + this.templates.set(provider.providerId, provider); }); + this.templateProvider.push(...Array.from(this.templates.keys())); + this.templateProvider.sort(); + } + + private mailServerSettingsForm(): void { this.registerDisableOnLoadFormControl(this.mailSettings.get('smtpProtocol')); this.registerDisableOnLoadFormControl(this.mailSettings.get('enableTls')); this.registerDisableOnLoadFormControl(this.mailSettings.get('enableProxy')); this.registerDisableOnLoadFormControl(this.mailSettings.get('changePassword')); + + this.mailSettings.get('enableTls').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(value => this.enableTls(value)); + this.mailSettings.get('enableProxy').valueChanges.pipe( takeUntil(this.destroy$) ).subscribe(() => { this.enableProxyChanged(); }); + this.mailSettings.get('changePassword').valueChanges.pipe( takeUntil(this.destroy$) ).subscribe((value) => { this.enableMailPassword(value); }); + + this.mailSettings.get('enableOauth2').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe( value => { + this.enableOauth2(value); + this.enableProviderTenantIdChanged(this.mailSettings.get('providerId').value); + if (value && !this.mailSettings.get('redirectUri').value) { + this.mailSettings.get('redirectUri').patchValue(this.redirectURI(), {emitEvent: false}); + } + }); + + this.mailSettings.get('providerTenantId').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(tenantId => { + const authorizationUri = this.templates.get(this.mailServerOauth2Provider.OFFICE_365).authorizationUri.replace('%s', `${tenantId}`); + const accessTokenUri = this.templates.get(this.mailServerOauth2Provider.OFFICE_365).accessTokenUri.replace('%s', `${tenantId}`); + this.mailSettings.get('authUri').patchValue(authorizationUri, {emitEvent: false}); + this.mailSettings.get('tokenUri').patchValue(accessTokenUri, {emitEvent: false}); + }); + + this.mailSettings.get('providerId').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe( value => { + if (value === this.mailServerOauth2Provider.CUSTOM || !value) { + this.mailSettings.reset({...this.adminSettings.jsonValue, ...this.defaultConfiguration}, {emitEvent: false}); + } else { + const config = this.templates.get(value); + this.helpLink = config.helpLink; + this.mailSettings.patchValue({ + smtpProtocol: SmtpProtocol[config.smtpProtocol], + smtpHost: config.smtpHost, + smtpPort: config.smtpPort, + timeout: config.timeout, + enableTls: config.enableTls, + tlsVersion: config.tlsVersion, + authUri: config.authorizationUri, + tokenUri: config.accessTokenUri, + scope: config.scope, + enableOauth2: false, + enableProxy: false, + proxyHost: '', + proxyPort: null, + proxyUser: '', + proxyPassword: '', + clientId: '', + clientSecret: '', + providerTenantId: '', + redirectUri: '' + }, {emitEvent: false}); + } + this.enableTls(this.mailSettings.get('enableTls').value); + this.enableOauth2(this.mailSettings.get('enableOauth2').value); + this.enableProviderTenantIdChanged(value); + }); + } + + private domainFormConfiguration(): void { + this.domainForm.get('name').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe( + value => this.mailSettings.get('redirectUri').patchValue( + this.redirectURI(this.domainForm.get('scheme').value, value), + {emitEvent: false} + ) + ); + this.domainForm.get('scheme').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe( + (value) => this.mailSettings.get('redirectUri').patchValue(this.redirectURI(value), {emitEvent: false}) + ); } - enableProxyChanged(): void { + private enableOauth2(value: boolean): void { + if (value) { + this.mailSettings.get('clientId').enable({emitEvent: false}); + this.mailSettings.get('clientSecret').enable({emitEvent: false}); + this.mailSettings.get('redirectUri').enable({emitEvent: false}); + if (this.mailSettings.get('providerId').value === this.mailServerOauth2Provider.CUSTOM) { + this.mailSettings.get('authUri').enable({emitEvent: false}); + this.mailSettings.get('tokenUri').enable({emitEvent: false}); + } else { + this.mailSettings.get('authUri').disable({emitEvent: false}); + this.mailSettings.get('tokenUri').disable({emitEvent: false}); + } + } else { + this.mailSettings.get('clientId').disable({emitEvent: false}); + this.mailSettings.get('clientSecret').disable({emitEvent: false}); + this.mailSettings.get('redirectUri').disable({emitEvent: false}); + this.mailSettings.get('authUri').disable({emitEvent: false}); + this.mailSettings.get('tokenUri').disable({emitEvent: false}); + } + } + + private enableProviderTenantIdChanged(value: string): void { + if (value === this.mailServerOauth2Provider.OFFICE_365 && this.mailSettings.get('enableOauth2').value) { + this.mailSettings.get('providerTenantId').enable({emitEvent: false}); + } else { + this.mailSettings.get('providerTenantId').disable({emitEvent: false}); + } + } + + private enableProxyChanged(): void { const enableProxy: boolean = this.mailSettings.get('enableProxy').value; if (enableProxy) { - this.mailSettings.get('proxyHost').enable(); - this.mailSettings.get('proxyPort').enable(); + this.mailSettings.get('proxyHost').enable({emitEvent: false}); + this.mailSettings.get('proxyPort').enable({emitEvent: false}); + this.mailSettings.get('proxyUser').enable({emitEvent: false}); + this.mailSettings.get('proxyPassword').enable({emitEvent: false}); } else { - this.mailSettings.get('proxyHost').disable(); - this.mailSettings.get('proxyPort').disable(); + this.mailSettings.get('proxyHost').disable({emitEvent: false}); + this.mailSettings.get('proxyPort').disable({emitEvent: false}); + this.mailSettings.get('proxyUser').disable({emitEvent: false}); + this.mailSettings.get('proxyPassword').disable({emitEvent: false}); } } - enableMailPassword(enable: boolean) { + private enableMailPassword(enable: boolean) { if (enable) { this.mailSettings.get('password').enable({emitEvent: false}); } else { @@ -134,14 +341,21 @@ export class MailServerComponent extends PageComponent implements OnInit, OnDest } } + private enableTls(enable: boolean): void { + if (enable) { + this.mailSettings.get('tlsVersion').enable({emitEvent: false}); + } else { + this.mailSettings.get('tlsVersion').disable({emitEvent: false}); + } + } + sendTestMail(): void { this.adminSettings.jsonValue = {...this.adminSettings.jsonValue, ...this.mailSettingsFormValue}; - this.adminService.sendTestMail(this.adminSettings).subscribe( - () => { - this.store.dispatch(new ActionNotificationShow({ message: this.translate.instant('admin.test-mail-sent'), - type: 'success' })); - } - ); + this.adminService.sendTestMail(this.adminSettings).subscribe({ + next: () => this.store.dispatch(new ActionNotificationShow({ message: this.translate.instant('admin.test-mail-sent'), + type: 'success' })), + error: error => this.store.dispatch(new ActionNotificationShow({message: error.error.message, type: 'error'})) + }); } save(): void { @@ -150,18 +364,88 @@ export class MailServerComponent extends PageComponent implements OnInit, OnDest (adminSettings) => { this.adminSettings = adminSettings; this.showChangePassword = true; - this.mailSettings.reset(this.adminSettings.jsonValue); + this.mailSettings.reset(this.adminSettings.jsonValue, {emitEvent: false}); + this.domainForm.reset(this.domainForm.value); + this.parseUrl(this.adminSettings.jsonValue.redirectUri); } ); } - confirmForm(): UntypedFormGroup { + generateAccessToken(): void { + this.adminService.generateAccessToken().subscribe( + uri => this.window.location.href = uri + ); + } + + redirectURI(schema?: DomainSchema, name?: string): string { + const domainInfo = this.domainForm.value; + if (domainInfo.name !== '') { + const protocol = isDefined(schema) ? schema.toLowerCase() : domainInfo.scheme.toLowerCase(); + const domainName = isDefined(name) ? name : domainInfo.name; + return `${protocol}://${domainName}${this.loginProcessingUrl}`; + } + return ''; + } + + private parseUrl(value: string): void { + if (value) { + const url = new URL(value); + this.domainForm.get('scheme').patchValue( + url.protocol.startsWith('https') ? DomainSchema.HTTPS : DomainSchema.HTTP, {emitEvent: false} + ); + this.domainForm.get('name').patchValue(url.host, {emitEvent: false}); + } + } + + get accessTokenButtonName(): string { + return this.translate.instant( + this.adminSettings.jsonValue.tokenGenerated ? 'admin.oauth2.update-access-token' : 'admin.oauth2.generate-access-token' + ); + } + + get accessTokenStatus(): string { + return this.translate.instant( + this.adminSettings.jsonValue.tokenGenerated ? 'admin.oauth2.token-status-generated' : 'admin.oauth2.token-status-not-generated' + ); + } + + confirmForm(): FormGroup { return this.mailSettings; } private get mailSettingsFormValue(): MailServerSettings { - const formValue = this.mailSettings.value; + const formValue = this.mailSettings.getRawValue() as Required; delete formValue.changePassword; return formValue; } + + trackByParams(index: number): number { + return index; + } + + removeScope(i: number): void { + const controller = this.mailSettings.get('scope') as UntypedFormArray; + controller.removeAt(i); + controller.markAsTouched(); + controller.markAsDirty(); + } + + addScope(event: MatChipInputEvent): void { + const input = event.chipInput.inputElement; + const value = event.value; + const controller = this.mailSettings.get('scope') as UntypedFormArray; + if ((value.trim() !== '')) { + controller.push(this.fb.control(value.trim())); + controller.markAsDirty(); + } + + if (input) { + input.value = ''; + } + } + + toggleEditMode(path: string): void { + this.mailSettings.get(path).disabled ? this.mailSettings.get(path).enable() : this.mailSettings.get(path).disable(); + } + } diff --git a/ui-ngx/src/app/shared/models/settings.models.ts b/ui-ngx/src/app/shared/models/settings.models.ts index 0cb02d6257..14f601dbe4 100644 --- a/ui-ngx/src/app/shared/models/settings.models.ts +++ b/ui-ngx/src/app/shared/models/settings.models.ts @@ -17,6 +17,7 @@ import { ValidatorFn } from '@angular/forms'; import { isNotEmptyStr, isNumber } from '@core/utils'; import { VersionCreateConfig } from '@shared/models/vc.models'; +import { HasUUID } from '@shared/models/id/has-uuid'; export const smtpPortPattern: RegExp = /^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/; @@ -25,16 +26,20 @@ export interface AdminSettings { jsonValue: T; } -export declare type SmtpProtocol = 'smtp' | 'smtps'; +export enum SmtpProtocol { + SMTP = 'smtp', + SMTPS = 'smtps' +} export interface MailServerSettings { - showChangePassword: boolean; + showChangePassword?: boolean; mailFrom: string; smtpProtocol: SmtpProtocol; smtpHost: string; smtpPort: number; timeout: number; enableTls: boolean; + tlsVersion: string; username: string; changePassword?: boolean; password?: string; @@ -43,6 +48,39 @@ export interface MailServerSettings { proxyPort: number; proxyUser: string; proxyPassword: string; + enableOauth2: boolean; + providerId?: string; + clientId?: string; + clientSecret?: string; + providerTenantId?: string; + authUri?: string; + tokenUri?: string; + scope?: Array; + redirectUri?: string; + tokenGenerated?: boolean; +} + +export enum MailServerOauth2Provider { + OFFICE_365 = 'OFFICE_365', + CUSTOM = 'CUSTOM' +} + +export interface MailConfigTemplate { + id: HasUUID; + createdTime: number; + name: string; + providerId: string; + helpLink: string; + scope: Array; + accessTokenUri: string; + authorizationUri: string; + enableTls: boolean; + tlsVersion: string; + smtpProtocol: SmtpProtocol; + smtpHost: string; + smtpPort: number; + timeout: number; + additionalInfo: any; } export interface GeneralSettings { 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 c4658c442a..e46bad540d 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -174,6 +174,7 @@ "domain-name-unique": "Domain name and protocol need to unique.", "domain-name-max-length": "Domain name should be less than 256", "error-verification-url": "A domain name shouldn't contain symbols '/' and ':'. Example: thingsboard.io", + "connection-settings": "Connection settings", "oauth2": { "access-token-uri": "Access token URI", "access-token-uri-required": "Access token URI is required.", @@ -264,7 +265,28 @@ "platform-android": "Android", "platform-ios": "iOS", "all-platforms": "All platforms", - "allowed-platforms": "Allowed platforms" + "smtp-provider": "SMTP provider", + "allowed-platforms": "Allowed platforms", + "authentication": "Authentication", + "basic": "Basic", + "provider": "Provider", + "redirect-url": "Redirect URI", + "domain-name": "Domain name", + "redirect-url-template": "Redirect URI template", + "microsoft-tenant-id": "Directory (tenant) Id", + "microsoft-tenant-id-required": "Directory (tenant) Id is required", + "token-uri": "Token URI", + "token-uri-required": "Token URI is required", + "redirect-uri": "Redirect URI", + "google-provider": "Google", + "microsoft-provider": "Office 365", + "sendgrid-provider": "Sendgrid", + "custom-provider": "Custom", + "generate-access-token": "Generate access token", + "update-access-token": "Update access token", + "access-token-status": "Access token status:", + "token-status-generated": "generated", + "token-status-not-generated": "not generated" }, "smpp-provider": { "smpp-version": "SMPP version", From 23d204e4d693e507c96b7c4d6e64b1b9bc60b64d Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 8 Jun 2023 11:53:00 +0200 Subject: [PATCH 150/207] added new default root cert for azure iot --- .../azure/BaltimoreCyberTrustRoot.crt.pem | 22 ------------- .../certs/azure/DigiCertGlobalRootG2.crt.pem | 22 +++++++++++++ .../common/util/AzureIotHubUtil.java | 31 +++++++++++++++---- 3 files changed, 47 insertions(+), 28 deletions(-) delete mode 100644 application/src/main/data/certs/azure/BaltimoreCyberTrustRoot.crt.pem create mode 100644 application/src/main/data/certs/azure/DigiCertGlobalRootG2.crt.pem diff --git a/application/src/main/data/certs/azure/BaltimoreCyberTrustRoot.crt.pem b/application/src/main/data/certs/azure/BaltimoreCyberTrustRoot.crt.pem deleted file mode 100644 index 2bd16ebd47..0000000000 --- a/application/src/main/data/certs/azure/BaltimoreCyberTrustRoot.crt.pem +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX -DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y -ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy -VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr -mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr -IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK -mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu -XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy -dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye -jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 -DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 -9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx -jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 -Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz -ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS -R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - diff --git a/application/src/main/data/certs/azure/DigiCertGlobalRootG2.crt.pem b/application/src/main/data/certs/azure/DigiCertGlobalRootG2.crt.pem new file mode 100644 index 0000000000..798e002751 --- /dev/null +++ b/application/src/main/data/certs/azure/DigiCertGlobalRootG2.crt.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- diff --git a/common/util/src/main/java/org/thingsboard/common/util/AzureIotHubUtil.java b/common/util/src/main/java/org/thingsboard/common/util/AzureIotHubUtil.java index ca9cc2660f..5beed77baf 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/AzureIotHubUtil.java +++ b/common/util/src/main/java/org/thingsboard/common/util/AzureIotHubUtil.java @@ -22,6 +22,7 @@ import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -36,7 +37,7 @@ public final class AzureIotHubUtil { private static final String DATA_DIR = "data"; private static final String CERTS_DIR = "certs"; private static final String AZURE_DIR = "azure"; - private static final String FILE_NAME = "BaltimoreCyberTrustRoot.crt.pem"; + private static final String FILE_NAME = "DigiCertGlobalRootG2.crt.pem"; private static final Path FULL_FILE_PATH; @@ -88,12 +89,30 @@ public final class AzureIotHubUtil { } public static String getDefaultCaCert() { - try { - return new String(Files.readAllBytes(FULL_FILE_PATH)); - } catch (IOException e) { - log.error("Failed to load Default CaCert file!!! [{}]", FULL_FILE_PATH.toString()); - throw new RuntimeException("Failed to load Default CaCert file!!!"); + byte[] fileBytes; + if (Files.exists(FULL_FILE_PATH)) { + try { + fileBytes = Files.readAllBytes(FULL_FILE_PATH); + } catch (IOException e) { + log.error("Failed to load Default CaCert file!!! [{}]", FULL_FILE_PATH, e); + throw new RuntimeException("Failed to load Default CaCert file!!!"); + } + } else { + Path azureDirectory = FULL_FILE_PATH.getParent(); + try (DirectoryStream stream = Files.newDirectoryStream(azureDirectory)) { + if (stream.iterator().hasNext()) { + Path firstFile = stream.iterator().next(); + fileBytes = Files.readAllBytes(firstFile); + } else { + log.error("Default CaCert file not found in the directory [{}]!!!", azureDirectory); + throw new RuntimeException("Default CaCert file not found in the directory!!!"); + } + } catch (IOException e) { + log.error("Failed to load Default CaCert file from the directory [{}]!!!", azureDirectory, e); + throw new RuntimeException("Failed to load Default CaCert file from the directory!!!"); + } } + return new String(fileBytes); } } From 6be3cda55ef23a5aed45cc2f8bad9d53a53861b0 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 8 Jun 2023 13:25:00 +0300 Subject: [PATCH 151/207] math node arguments/result key fields templatization --- .../rule/engine/math/TbMathArgumentValue.java | 20 +++--- .../rule/engine/math/TbMathNode.java | 46 +++++++------- .../engine/math/TbMathArgumentValueTest.java | 18 +++--- .../rule/engine/math/TbMathNodeTest.java | 61 +++++++++++++++---- 4 files changed, 92 insertions(+), 53 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathArgumentValue.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathArgumentValue.java index 9985446dd3..f740aebf4a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathArgumentValue.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathArgumentValue.java @@ -43,19 +43,18 @@ public class TbMathArgumentValue { throw new RuntimeException(error); } - public static TbMathArgumentValue fromMessageBody(TbMathArgument arg, Optional jsonNodeOpt) { - String key = arg.getKey(); + public static TbMathArgumentValue fromMessageBody(TbMathArgument arg, String argKey, Optional jsonNodeOpt) { Double defaultValue = arg.getDefaultValue(); if (jsonNodeOpt.isEmpty()) { return defaultOrThrow(defaultValue, "Message body is empty!"); } var json = jsonNodeOpt.get(); - if (!json.has(key)) { - return defaultOrThrow(defaultValue, "Message body has no '" + key + "'!"); + if (!json.has(argKey)) { + return defaultOrThrow(defaultValue, "Message body has no '" + argKey + "'!"); } - JsonNode valueNode = json.get(key); + JsonNode valueNode = json.get(argKey); if (valueNode.isNull()) { - return defaultOrThrow(defaultValue, "Message body has null '" + key + "'!"); + return defaultOrThrow(defaultValue, "Message body has null '" + argKey + "'!"); } double value; if (valueNode.isNumber()) { @@ -69,7 +68,7 @@ public class TbMathArgumentValue { throw new RuntimeException("Can't convert value '" + valueNode.asText() + "' to double!"); } } else { - return defaultOrThrow(defaultValue, "Message value is empty for '" + key + "'!"); + return defaultOrThrow(defaultValue, "Message value is empty for '" + argKey + "'!"); } } else { throw new RuntimeException("Can't convert value '" + valueNode.toString() + "' to double!"); @@ -77,15 +76,14 @@ public class TbMathArgumentValue { return new TbMathArgumentValue(value); } - public static TbMathArgumentValue fromMessageMetadata(TbMathArgument arg, TbMsgMetaData metaData) { - String key = arg.getKey(); + public static TbMathArgumentValue fromMessageMetadata(TbMathArgument arg, String argKey, TbMsgMetaData metaData) { Double defaultValue = arg.getDefaultValue(); if (metaData == null) { return defaultOrThrow(defaultValue, "Message metadata is empty!"); } - var value = metaData.getValue(key); + var value = metaData.getValue(argKey); if (StringUtils.isEmpty(value)) { - return defaultOrThrow(defaultValue, "Message metadata has no '" + key + "'!"); + return defaultOrThrow(defaultValue, "Message metadata has no '" + argKey + "'!"); } return fromString(value); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java index eff3917c14..26ec656443 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java @@ -51,6 +51,8 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; +import static org.thingsboard.rule.engine.math.TbMathArgumentType.CONSTANT; + @SuppressWarnings("UnstableApiUsage") @Slf4j @RuleNode( @@ -121,7 +123,7 @@ public class TbMathNode implements TbNode { var argumentValues = Futures.allAsList(arguments.stream() .map(arg -> resolveArguments(ctx, msg, msgBodyOpt, arg)).collect(Collectors.toList())); ListenableFuture resultMsgFuture = Futures.transformAsync(argumentValues, args -> - updateMsgAndDb(ctx, msg, msgBodyOpt, calculateResult(ctx, msg, args)), ctx.getDbCallbackExecutor()); + updateMsgAndDb(ctx, msg, msgBodyOpt, calculateResult(args)), ctx.getDbCallbackExecutor()); DonAsynchron.withCallback(resultMsgFuture, resultMsg -> { try { ctx.tellSuccess(resultMsg); @@ -155,17 +157,18 @@ public class TbMathNode implements TbNode { private ListenableFuture updateMsgAndDb(TbContext ctx, TbMsg msg, Optional msgBodyOpt, double result) { TbMathResult mathResultDef = config.getResult(); + String mathResultKey = !mathResultDef.getType().equals(CONSTANT) ? TbNodeUtils.processPattern(mathResultDef.getKey(), msg) : mathResultDef.getKey(); switch (mathResultDef.getType()) { case MESSAGE_BODY: - return Futures.immediateFuture(addToBody(msg, mathResultDef, msgBodyOpt, result)); + return Futures.immediateFuture(addToBody(msg, mathResultDef, mathResultKey, msgBodyOpt, result)); case MESSAGE_METADATA: - return Futures.immediateFuture(addToMeta(msg, mathResultDef, result)); + return Futures.immediateFuture(addToMeta(msg, mathResultDef, mathResultKey, result)); case ATTRIBUTE: ListenableFuture attrSave = saveAttribute(ctx, msg, result, mathResultDef); - return Futures.transform(attrSave, attr -> addToBodyAndMeta(msg, msgBodyOpt, result, mathResultDef), ctx.getDbCallbackExecutor()); + return Futures.transform(attrSave, attr -> addToBodyAndMeta(msg, msgBodyOpt, result, mathResultDef, mathResultKey), ctx.getDbCallbackExecutor()); case TIME_SERIES: ListenableFuture tsSave = saveTimeSeries(ctx, msg, result, mathResultDef); - return Futures.transform(tsSave, ts -> addToBodyAndMeta(msg, msgBodyOpt, result, mathResultDef), ctx.getDbCallbackExecutor()); + return Futures.transform(tsSave, ts -> addToBodyAndMeta(msg, msgBodyOpt, result, mathResultDef, mathResultKey), ctx.getDbCallbackExecutor()); default: throw new RuntimeException("Result type is not supported: " + mathResultDef.getType() + "!"); } @@ -217,38 +220,38 @@ public class TbMathNode implements TbNode { return msgBodyOpt; } - private TbMsg addToBodyAndMeta(TbMsg msg, Optional msgBodyOpt, double result, TbMathResult mathResultDef) { + private TbMsg addToBodyAndMeta(TbMsg msg, Optional msgBodyOpt, double result, TbMathResult mathResultDef, String mathResultKey) { TbMsg tmpMsg = msg; if (mathResultDef.isAddToBody()) { - tmpMsg = addToBody(tmpMsg, mathResultDef, msgBodyOpt, result); + tmpMsg = addToBody(tmpMsg, mathResultDef, mathResultKey, msgBodyOpt, result); } if (mathResultDef.isAddToMetadata()) { - tmpMsg = addToMeta(tmpMsg, mathResultDef, result); + tmpMsg = addToMeta(tmpMsg, mathResultDef, mathResultKey, result); } return tmpMsg; } - private TbMsg addToBody(TbMsg msg, TbMathResult mathResultDef, Optional msgBodyOpt, double result) { + private TbMsg addToBody(TbMsg msg, TbMathResult mathResultDef, String mathResultKey, Optional msgBodyOpt, double result) { ObjectNode body = msgBodyOpt.get(); if (isIntegerResult(mathResultDef, config.getOperation())) { - body.put(mathResultDef.getKey(), toIntValue(mathResultDef, result)); + body.put(mathResultKey, toIntValue(mathResultDef, result)); } else { - body.put(mathResultDef.getKey(), toDoubleValue(mathResultDef, result)); + body.put(mathResultKey, toDoubleValue(mathResultDef, result)); } return TbMsg.transformMsgData(msg, JacksonUtil.toString(body)); } - private TbMsg addToMeta(TbMsg msg, TbMathResult mathResultDef, double result) { + private TbMsg addToMeta(TbMsg msg, TbMathResult mathResultDef, String mathResultKey, double result) { var md = msg.getMetaData(); if (isIntegerResult(mathResultDef, config.getOperation())) { - md.putValue(mathResultDef.getKey(), Long.toString(toIntValue(mathResultDef, result))); + md.putValue(mathResultKey, Long.toString(toIntValue(mathResultDef, result))); } else { - md.putValue(mathResultDef.getKey(), Double.toString(toDoubleValue(mathResultDef, result))); + md.putValue(mathResultKey, Double.toString(toDoubleValue(mathResultDef, result))); } return TbMsg.transformMsg(msg, md); } - private double calculateResult(TbContext ctx, TbMsg msg, List args) { + private double calculateResult(List args) { switch (config.getOperation()) { case ADD: return apply(args.get(0), args.get(1), Double::sum); @@ -345,21 +348,22 @@ public class TbMathNode implements TbNode { } private ListenableFuture resolveArguments(TbContext ctx, TbMsg msg, Optional msgBodyOpt, TbMathArgument arg) { + String argKey = !arg.getType().equals(CONSTANT) ? TbNodeUtils.processPattern(arg.getKey(), msg) : arg.getKey(); switch (arg.getType()) { case CONSTANT: return Futures.immediateFuture(TbMathArgumentValue.constant(arg)); case MESSAGE_BODY: - return Futures.immediateFuture(TbMathArgumentValue.fromMessageBody(arg, msgBodyOpt)); + return Futures.immediateFuture(TbMathArgumentValue.fromMessageBody(arg, argKey, msgBodyOpt)); case MESSAGE_METADATA: - return Futures.immediateFuture(TbMathArgumentValue.fromMessageMetadata(arg, msg.getMetaData())); + return Futures.immediateFuture(TbMathArgumentValue.fromMessageMetadata(arg, argKey, msg.getMetaData())); case ATTRIBUTE: String scope = getAttributeScope(arg.getAttributeScope()); - return Futures.transform(ctx.getAttributesService().find(ctx.getTenantId(), msg.getOriginator(), scope, arg.getKey()), - opt -> getTbMathArgumentValue(arg, opt, "Attribute: " + arg.getKey() + " with scope: " + scope + " not found for entity: " + msg.getOriginator()) + return Futures.transform(ctx.getAttributesService().find(ctx.getTenantId(), msg.getOriginator(), scope, argKey), + opt -> getTbMathArgumentValue(arg, opt, "Attribute: " + argKey + " with scope: " + scope + " not found for entity: " + msg.getOriginator()) , MoreExecutors.directExecutor()); case TIME_SERIES: - return Futures.transform(ctx.getTimeseriesService().findLatest(ctx.getTenantId(), msg.getOriginator(), arg.getKey()), - opt -> getTbMathArgumentValue(arg, opt, "Time-series: " + arg.getKey() + " not found for entity: " + msg.getOriginator()) + return Futures.transform(ctx.getTimeseriesService().findLatest(ctx.getTenantId(), msg.getOriginator(), argKey), + opt -> getTbMathArgumentValue(arg, opt, "Time-series: " + argKey + " not found for entity: " + msg.getOriginator()) , MoreExecutors.directExecutor()); default: throw new RuntimeException("Unsupported argument type: " + arg.getType() + "!"); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathArgumentValueTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathArgumentValueTest.java index 984d9bfb72..eccc9bb932 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathArgumentValueTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathArgumentValueTest.java @@ -31,7 +31,7 @@ public class TbMathArgumentValueTest { public void test_fromMessageBody_then_defaultValue() { TbMathArgument tbMathArgument = new TbMathArgument(TbMathArgumentType.MESSAGE_BODY, "TestKey"); tbMathArgument.setDefaultValue(5.0); - TbMathArgumentValue result = TbMathArgumentValue.fromMessageBody(tbMathArgument, Optional.ofNullable(JacksonUtil.newObjectNode())); + TbMathArgumentValue result = TbMathArgumentValue.fromMessageBody(tbMathArgument, tbMathArgument.getKey(), Optional.ofNullable(JacksonUtil.newObjectNode())); Assert.assertEquals(5.0, result.getValue(), 0d); } @@ -39,7 +39,7 @@ public class TbMathArgumentValueTest { public void test_fromMessageBody_then_emptyBody() { TbMathArgument tbMathArgument = new TbMathArgument(TbMathArgumentType.MESSAGE_BODY, "TestKey"); Throwable thrown = assertThrows(RuntimeException.class, () -> { - TbMathArgumentValue result = TbMathArgumentValue.fromMessageBody(tbMathArgument, Optional.empty()); + TbMathArgumentValue result = TbMathArgumentValue.fromMessageBody(tbMathArgument, tbMathArgument.getKey(), Optional.empty()); }); Assert.assertNotNull(thrown.getMessage()); } @@ -47,7 +47,7 @@ public class TbMathArgumentValueTest { @Test public void test_fromMessageBody_then_noKey() { TbMathArgument tbMathArgument = new TbMathArgument(TbMathArgumentType.MESSAGE_BODY, "TestKey"); - Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, Optional.ofNullable(JacksonUtil.newObjectNode()))); + Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, tbMathArgument.getKey(), Optional.ofNullable(JacksonUtil.newObjectNode()))); Assert.assertNotNull(thrown.getMessage()); } @@ -58,12 +58,12 @@ public class TbMathArgumentValueTest { msgData.putNull("TestKey"); //null value - Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, Optional.of(msgData))); + Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, tbMathArgument.getKey(), Optional.of(msgData))); Assert.assertNotNull(thrown.getMessage()); //empty value msgData.put("TestKey", ""); - thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, Optional.of(msgData))); + thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, tbMathArgument.getKey(), Optional.of(msgData))); Assert.assertNotNull(thrown.getMessage()); } @@ -74,26 +74,26 @@ public class TbMathArgumentValueTest { msgData.put("TestKey", "Test"); //string value - Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, Optional.of(msgData))); + Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, tbMathArgument.getKey(), Optional.of(msgData))); Assert.assertNotNull(thrown.getMessage()); //object value msgData.set("TestKey", JacksonUtil.newObjectNode()); - thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, Optional.of(msgData))); + thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageBody(tbMathArgument, tbMathArgument.getKey(), Optional.of(msgData))); Assert.assertNotNull(thrown.getMessage()); } @Test public void test_fromMessageMetadata_then_noKey() { TbMathArgument tbMathArgument = new TbMathArgument(TbMathArgumentType.MESSAGE_BODY, "TestKey"); - Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageMetadata(tbMathArgument, new TbMsgMetaData())); + Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageMetadata(tbMathArgument, tbMathArgument.getKey(), new TbMsgMetaData())); Assert.assertNotNull(thrown.getMessage()); } @Test public void test_fromMessageMetadata_then_valueEmpty() { TbMathArgument tbMathArgument = new TbMathArgument(TbMathArgumentType.MESSAGE_BODY, "TestKey"); - Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageMetadata(tbMathArgument, null)); + Throwable thrown = assertThrows(RuntimeException.class, () -> TbMathArgumentValue.fromMessageMetadata(tbMathArgument, tbMathArgument.getKey(), null)); Assert.assertNotNull(thrown.getMessage()); } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java index 69d1b46dbe..2efc438f8f 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java @@ -16,7 +16,10 @@ package org.thingsboard.rule.engine.math; import com.datastax.oss.driver.api.core.uuid.Uuids; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; +import lombok.extern.slf4j.Slf4j; +import org.awaitility.Awaitility; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -26,6 +29,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.test.util.ReflectionTestUtils; import org.thingsboard.common.util.AbstractListeningExecutor; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; @@ -47,7 +51,11 @@ import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.timeseries.TimeseriesService; import java.util.Arrays; +import java.util.List; import java.util.Optional; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -57,6 +65,7 @@ import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +@Slf4j @RunWith(MockitoJUnitRunner.class) public class TbMathNodeTest { @@ -130,24 +139,52 @@ public class TbMathNodeTest { @Test public void testExp4j() { var node = initNodeWithCustomFunction("2a+3b", - new TbMathResult(TbMathArgumentType.MESSAGE_BODY, "result", 2, false, false, null), - new TbMathArgument(TbMathArgumentType.MESSAGE_BODY, "a"), - new TbMathArgument(TbMathArgumentType.MESSAGE_BODY, "b") + new TbMathResult(TbMathArgumentType.MESSAGE_BODY, "${key1}", 2, false, false, null), + new TbMathArgument("a", TbMathArgumentType.MESSAGE_BODY, "${key2}"), + new TbMathArgument("b", TbMathArgumentType.MESSAGE_BODY, "$[key3]") ); - TbMsg msg = TbMsg.newMsg("TEST", originator, new TbMsgMetaData(), JacksonUtil.newObjectNode().put("a", 2).put("b", 2).toString()); + TbMsgMetaData metaData = new TbMsgMetaData(); + metaData.putValue("key1", "firstMsgResult"); + metaData.putValue("key2", "argumentA"); + ObjectNode msgNode = JacksonUtil.newObjectNode() + .put("key3", "argumentB").put("argumentA", 2).put("argumentB", 2); + TbMsg msg = TbMsg.newMsg("TEST", originator, metaData, msgNode.toString()); node.onMsg(ctx, msg); - ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(TbMsg.class); - Mockito.verify(ctx, Mockito.timeout(5000)).tellSuccess(msgCaptor.capture()); + ConcurrentMap semaphores = (ConcurrentMap) ReflectionTestUtils.getField(node, "semaphores"); + Assert.assertNotNull(semaphores); + Semaphore originatorSemaphore = semaphores.get(originator); + Assert.assertNotNull(originatorSemaphore); - TbMsg resultMsg = msgCaptor.getValue(); - Assert.assertNotNull(resultMsg); - Assert.assertNotNull(resultMsg.getData()); - var resultJson = JacksonUtil.toJsonNode(resultMsg.getData()); - Assert.assertTrue(resultJson.has("result")); - Assert.assertEquals(10, resultJson.get("result").asInt()); + metaData.putValue("key1", "secondMsgResult"); + metaData.putValue("key2", "argumentC"); + msgNode = JacksonUtil.newObjectNode() + .put("key3", "argumentD").put("argumentC", 4).put("argumentD", 3); + msg = TbMsg.newMsg("TEST", originator, metaData, msgNode.toString()); + + node.onMsg(ctx, msg); + + Awaitility.await("Semaphore released").atMost(5, TimeUnit.SECONDS).until(semaphores.get(originator)::tryAcquire); + + ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(TbMsg.class); + Mockito.verify(ctx, Mockito.times(2)).tellSuccess(msgCaptor.capture()); + + List resultMsgs = msgCaptor.getAllValues(); + Assert.assertFalse(resultMsgs.isEmpty()); + Assert.assertEquals(2, resultMsgs.size()); + + for (int i = 0; i < resultMsgs.size(); i++) { + TbMsg outMsg = resultMsgs.get(i); + Assert.assertNotNull(outMsg); + Assert.assertNotNull(outMsg.getData()); + var resultJson = JacksonUtil.toJsonNode(outMsg.getData()); + String resultKey = i == 0 ? "firstMsgResult" : "secondMsgResult"; + Assert.assertTrue(resultJson.has(resultKey)); + Assert.assertEquals(i == 0 ? 10 : 17, resultJson.get(resultKey).asInt()); + } + semaphores.remove(originator); } @Test From 080a40983964a818b5eb9bd91c4942db252af92d Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Thu, 8 Jun 2023 15:52:40 +0300 Subject: [PATCH 152/207] Check edge session before removal to avoid removing live session --- .../service/edge/rpc/EdgeGrpcService.java | 33 +++++++++++-------- .../service/edge/rpc/EdgeGrpcSession.java | 8 ++--- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 5171a6037f..92a7c27867 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -380,21 +380,26 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i } } - private void onEdgeDisconnect(EdgeId edgeId) { - log.info("[{}] edge disconnected!", edgeId); - EdgeGrpcSession removed = sessions.remove(edgeId); - final Lock newEventLock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); - newEventLock.lock(); - try { - sessionNewEvents.remove(edgeId); - } finally { - newEventLock.unlock(); + private void onEdgeDisconnect(EdgeId edgeId, UUID sessionId) { + log.info("[{}][{}] edge disconnected!", edgeId, sessionId); + EdgeGrpcSession toRemove = sessions.get(edgeId); + if (toRemove.getSessionId().equals(sessionId)) { + toRemove = sessions.remove(edgeId); + final Lock newEventLock = sessionNewEventsLocks.computeIfAbsent(edgeId, id -> new ReentrantLock()); + newEventLock.lock(); + try { + sessionNewEvents.remove(edgeId); + } finally { + newEventLock.unlock(); + } + save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, false); + long lastDisconnectTs = System.currentTimeMillis(); + save(edgeId, DefaultDeviceStateService.LAST_DISCONNECT_TIME, lastDisconnectTs); + pushRuleEngineMessage(toRemove.getEdge().getTenantId(), edgeId, lastDisconnectTs, DISCONNECT_EVENT); + cancelScheduleEdgeEventsCheck(edgeId); + } else { + log.debug("[{}] edge session [{}] is not available anymore, nothing to remove. most probably this session is already outdated!", edgeId, sessionId); } - save(edgeId, DefaultDeviceStateService.ACTIVITY_STATE, false); - long lastDisconnectTs = System.currentTimeMillis(); - save(edgeId, DefaultDeviceStateService.LAST_DISCONNECT_TIME, lastDisconnectTs); - pushRuleEngineMessage(removed.getEdge().getTenantId(), edgeId, lastDisconnectTs, DISCONNECT_EVENT); - cancelScheduleEdgeEventsCheck(edgeId); } private void save(EdgeId edgeId, String key, long value) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 33aed92682..1dd0f31c20 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -92,7 +92,7 @@ public final class EdgeGrpcSession implements Closeable { private final UUID sessionId; private final BiConsumer sessionOpenListener; - private final Consumer sessionCloseListener; + private final BiConsumer sessionCloseListener; private final EdgeSessionState sessionState = new EdgeSessionState(); @@ -111,7 +111,7 @@ public final class EdgeGrpcSession implements Closeable { private ScheduledExecutorService sendDownlinkExecutorService; EdgeGrpcSession(EdgeContextComponent ctx, StreamObserver outputStream, BiConsumer sessionOpenListener, - Consumer sessionCloseListener, ScheduledExecutorService sendDownlinkExecutorService, int maxInboundMessageSize) { + BiConsumer sessionCloseListener, ScheduledExecutorService sendDownlinkExecutorService, int maxInboundMessageSize) { this.sessionId = UUID.randomUUID(); this.ctx = ctx; this.outputStream = outputStream; @@ -180,7 +180,7 @@ public final class EdgeGrpcSession implements Closeable { connected = false; if (edge != null) { try { - sessionCloseListener.accept(edge.getId()); + sessionCloseListener.accept(edge.getId(), sessionId); } catch (Exception ignored) { } } @@ -288,7 +288,7 @@ public final class EdgeGrpcSession implements Closeable { } catch (Exception e) { log.error("[{}] Failed to send downlink message [{}]", this.sessionId, downlinkMsg, e); connected = false; - sessionCloseListener.accept(edge.getId()); + sessionCloseListener.accept(edge.getId(), sessionId); } finally { downlinkMsgLock.unlock(); } From 10258426686119fdd8bca01806c804d0bfb76cbc Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 8 Jun 2023 16:18:45 +0300 Subject: [PATCH 153/207] fixed license --- .../mail/DefaultTbMailConfigTemplateService.java | 15 +++++++++++++++ .../service/mail/TbMailConfigTemplateService.java | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java index 3d4cb261c7..2272a42b5b 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.service.mail; import com.fasterxml.jackson.databind.JsonNode; diff --git a/application/src/main/java/org/thingsboard/server/service/mail/TbMailConfigTemplateService.java b/application/src/main/java/org/thingsboard/server/service/mail/TbMailConfigTemplateService.java index 2475fe7513..b69ae0977c 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/TbMailConfigTemplateService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/TbMailConfigTemplateService.java @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.service.mail; import com.fasterxml.jackson.databind.JsonNode; From 9dd10b0b75e398af3c95935ce73d239cad809e17 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 8 Jun 2023 15:51:10 +0200 Subject: [PATCH 154/207] fixed Iterator already obtained --- .../java/org/thingsboard/common/util/AzureIotHubUtil.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/util/src/main/java/org/thingsboard/common/util/AzureIotHubUtil.java b/common/util/src/main/java/org/thingsboard/common/util/AzureIotHubUtil.java index 5beed77baf..b80427d0de 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/AzureIotHubUtil.java +++ b/common/util/src/main/java/org/thingsboard/common/util/AzureIotHubUtil.java @@ -27,6 +27,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; +import java.util.Iterator; @Slf4j public final class AzureIotHubUtil { @@ -100,8 +101,9 @@ public final class AzureIotHubUtil { } else { Path azureDirectory = FULL_FILE_PATH.getParent(); try (DirectoryStream stream = Files.newDirectoryStream(azureDirectory)) { - if (stream.iterator().hasNext()) { - Path firstFile = stream.iterator().next(); + Iterator iterator = stream.iterator(); + if (iterator.hasNext()) { + Path firstFile = iterator.next(); fileBytes = Files.readAllBytes(firstFile); } else { log.error("Default CaCert file not found in the directory [{}]!!!", azureDirectory); From 5102e5fda7e570572c60b485fcf47d591cd3d4f0 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Thu, 8 Jun 2023 17:11:31 +0300 Subject: [PATCH 155/207] UI: Refactoring for touch event --- .../widget/lib/flot-widget.models.ts | 4 +-- .../home/components/widget/lib/flot-widget.ts | 28 ++++--------------- .../chart/flot-widget-settings.component.html | 22 +++------------ .../chart/flot-widget-settings.component.ts | 4 +-- .../assets/locale/locale.constant-en_US.json | 5 +--- ui-ngx/src/typings/jquery.flot.typings.d.ts | 1 + 6 files changed, 15 insertions(+), 49 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts index 46bafd69ca..844d7540ff 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.models.ts @@ -136,7 +136,7 @@ export interface TbFlotYAxisSettings { export interface TbFlotBaseSettings { stack: boolean; - enableSelection: FlotSelection; + enableSelection: boolean; shadowSize: number; fontColor: string; fontSize: number; @@ -183,8 +183,6 @@ export interface TbFlotGraphSettings extends TbFlotBaseSettings, export declare type BarAlignment = 'left' | 'right' | 'center'; -export declare type FlotSelection = 'enable' | 'disable' | 'mobile' | 'desktop'; - export interface TbFlotBarSettings extends TbFlotBaseSettings, TbFlotThresholdsSettings, TbFlotComparisonSettings, TbFlotCustomLegendSettings { defaultBarWidth: number; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts index 4f3db3d91b..1d20068e20 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts @@ -37,7 +37,7 @@ import { widgetType } from '@app/shared/models/widget.models'; import { - ChartType, FlotSelection, + ChartType, TbFlotAxisOptions, TbFlotHoverInfo, TbFlotKeySettings, @@ -117,7 +117,7 @@ export class TbFlot { private mouseleaveHandler = this.onFlotMouseLeave.bind(this); private flotClickHandler = this.onFlotClick.bind(this); - private enableSelection: FlotSelection; + private enableSelection: boolean; private selectionMode: 'x' | null; private readonly showTooltip: boolean; @@ -134,8 +134,8 @@ export class TbFlot { this.chartType = this.chartType || 'line'; this.settings = ctx.settings as TbFlotSettings; this.utils = this.ctx.$injector.get(UtilsService); - this.enableSelection = isDefined(this.settings.enableSelection) ? this.settings.enableSelection : 'enable'; - this.checkSelectionMode(); + this.enableSelection = isDefined(this.settings.enableSelection) ? this.settings.enableSelection : true; + this.selectionMode = this.enableSelection ? 'x' : null; this.showTooltip = isDefined(this.settings.showTooltip) ? this.settings.showTooltip : true; this.tooltip = this.showTooltip ? $('#flot-series-tooltip') : null; if (this.tooltip?.length === 0) { @@ -172,7 +172,7 @@ export class TbFlot { }; if (this.chartType === 'line' || this.chartType === 'bar' || this.chartType === 'state') { - this.options.selection = { mode: this.selectionMode }; + this.options.selection = { mode: this.selectionMode, touch: true }; this.options.xaxes = []; this.xaxis = { mode: 'time', @@ -589,22 +589,6 @@ export class TbFlot { this.createPlot(); } - mobileModeChanged() { - this.checkSelectionMode(); - this.options.selection = { mode: this.selectionMode }; - this.redrawPlot(); - } - - private checkSelectionMode() { - if (this.enableSelection === 'enable' || - this.enableSelection === 'mobile' && this.ctx.isMobile || - this.enableSelection === 'desktop' && !this.ctx.isMobile) { - this.selectionMode = 'x'; - } else { - this.selectionMode = null; - } - } - public update() { if (this.updateTimeoutHandle) { clearTimeout(this.updateTimeoutHandle); @@ -1272,7 +1256,7 @@ export class TbFlot { this.$element.css('pointer-events', ''); this.$element.addClass('mouse-events'); if (this.chartType !== 'pie') { - this.options.selection = {mode: this.selectionMode}; + this.options.selection = {mode: this.selectionMode, touch: true}; this.$element.bind('plotselected', this.flotSelectHandler); this.$element.bind('dblclick', this.dblclickHandler); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html index 00173841e6..9baf89cbd4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html @@ -19,26 +19,12 @@
widgets.chart.common-settings
- + {{ 'widgets.chart.enable-stacking-mode' | translate }} - - widgets.chart.selection - - - {{ 'widgets.chart.selection-enable' | translate }} - - - {{ 'widgets.chart.selection-disable' | translate }} - - - {{ 'widgets.chart.selection-mobile' | translate }} - - - {{ 'widgets.chart.selection-desktop' | translate }} - - - + + {{ 'widgets.chart.enable-selection-mode' | translate }} +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts index 92e7309b4b..abcfdeebc3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts @@ -45,7 +45,7 @@ import { defaultLegendConfig, widgetType } from '@shared/models/widget.models'; export const flotDefaultSettings = (chartType: ChartType): Partial => { const settings: Partial = { stack: false, - enableSelection: 'enable', + enableSelection: true, fontColor: '#545454', fontSize: 10, showTooltip: true, @@ -149,7 +149,7 @@ export class FlotWidgetSettingsComponent extends PageComponent implements OnInit // Common settings stack: [false, []], - enableSelection: ['enable', []], + enableSelection: [true, []], fontSize: [10, [Validators.min(0)]], fontColor: ['#545454', []], 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 4eca6e48d9..724fd11893 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4214,10 +4214,7 @@ "common-settings": "Common settings", "enable-stacking-mode": "Enable stacking mode", "selection": "Time range selection", - "selection-enable": "Enable", - "selection-disable": "Disable", - "selection-mobile": "Only mobile", - "selection-desktop": "Only desktop", + "enable-selection-mode": "Enable stacking mode", "line-shadow-size": "Line shadow size", "display-smooth-lines": "Display smooth (curved) lines", "default-bar-width": "Default bar width for non-aggregated data (milliseconds)", diff --git a/ui-ngx/src/typings/jquery.flot.typings.d.ts b/ui-ngx/src/typings/jquery.flot.typings.d.ts index 5bcc9b9b3e..e832a36e7a 100644 --- a/ui-ngx/src/typings/jquery.flot.typings.d.ts +++ b/ui-ngx/src/typings/jquery.flot.typings.d.ts @@ -119,6 +119,7 @@ interface JQueryPlotSelection { color?: string; shape?: JQueryPlotSelectionShape; minSize?: number; + touch?: boolean; } interface JQueryPlotSelectionRanges { From f5aba152cf164d7e8ac9d3c8ee4b69ef1ec81d33 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Thu, 8 Jun 2023 17:30:09 +0300 Subject: [PATCH 156/207] UI: Refactoring locale --- ui-ngx/src/assets/locale/locale.constant-en_US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 724fd11893..a097c16dc3 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4214,7 +4214,7 @@ "common-settings": "Common settings", "enable-stacking-mode": "Enable stacking mode", "selection": "Time range selection", - "enable-selection-mode": "Enable stacking mode", + "enable-selection-mode": "Enable selection mode", "line-shadow-size": "Line shadow size", "display-smooth-lines": "Display smooth (curved) lines", "default-bar-width": "Default bar width for non-aggregated data (milliseconds)", From d34a65eadaebb6bb3c08b96ccf455f3d89feae4b Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 8 Jun 2023 17:44:20 +0300 Subject: [PATCH 157/207] Resources access for Customer Users --- .../main/data/upgrade/3.5.1/schema_update.sql | 4 +- .../controller/TbResourceController.java | 42 ++++++++++--------- .../resource/DefaultTbResourceService.java | 2 +- .../permission/CustomerUserPermissions.java | 25 +++++++++++ .../server/controller/AbstractWebTest.java | 38 +++++++++++++++++ .../controller/TbResourceControllerTest.java | 20 ++++++++- .../server/common/data/ResourceType.java | 20 +++++---- .../server/common/data/TbResource.java | 2 +- .../server/common/data/TbResourceInfo.java | 8 ++-- .../server/dao/model/ModelConstants.java | 2 +- .../dao/model/sql/TbResourceEntity.java | 10 ++--- .../dao/model/sql/TbResourceInfoEntity.java | 8 ++-- .../main/resources/sql/schema-entities.sql | 2 +- 13 files changed, 135 insertions(+), 48 deletions(-) diff --git a/application/src/main/data/upgrade/3.5.1/schema_update.sql b/application/src/main/data/upgrade/3.5.1/schema_update.sql index 9000acc69e..58031ce5c0 100644 --- a/application/src/main/data/upgrade/3.5.1/schema_update.sql +++ b/application/src/main/data/upgrade/3.5.1/schema_update.sql @@ -54,8 +54,8 @@ $$; -- NOTIFICATION CONFIGS VERSION CONTROL END ALTER TABLE resource - ADD COLUMN IF NOT EXISTS hash_code varchar; + ADD COLUMN IF NOT EXISTS etag varchar; UPDATE resource - SET hash_code = encode(sha256(decode(resource.data, 'base64')),'hex') WHERE resource.data is not null; + SET etag = encode(sha256(decode(resource.data, 'base64')),'hex') WHERE resource.data is not null; diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index 7bd1000443..94e318f37c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -15,8 +15,6 @@ */ package org.thingsboard.server.controller; -import com.google.common.hash.HashCode; -import com.google.common.hash.Hashing; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; @@ -49,13 +47,13 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.resource.TbResourceService; -import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import java.util.Base64; import java.util.List; +import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER; import static org.thingsboard.server.controller.ControllerConstants.LWM2M_OBJECT_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; @@ -82,6 +80,7 @@ import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LI @RequiredArgsConstructor public class TbResourceController extends BaseController { + private static final String DOWNLOAD_RESOURCE_IF_NOT_CHANGED = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed."; private final TbResourceService tbResourceService; public static final String RESOURCE_ID = "resourceId"; @@ -105,39 +104,44 @@ public class TbResourceController extends BaseController { .body(resource); } - @ApiOperation(value = "Download LWM2M Resource (downloadLwm2mResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Download LWM2M Resource (downloadLwm2mResourceIfChanged)", notes = DOWNLOAD_RESOURCE_IF_NOT_CHANGED + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - @RequestMapping(value = "/resource/lwm2m/{resourceId}/download", method = RequestMethod.GET) + @RequestMapping(value = "/resource/lwm2m/{resourceId}/download", method = RequestMethod.GET, produces = "application/xml") @ResponseBody public ResponseEntity downloadLwm2mResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { + @PathVariable(RESOURCE_ID) String strResourceId, + @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { return downloadResourceIfChanged(ResourceType.LWM2M_MODEL, strResourceId, etag); } - @ApiOperation(value = "Download PKCS_12 Resource (downloadPkcs12ResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Download PKCS_12 Resource (downloadPkcs12ResourceIfChanged)", notes = DOWNLOAD_RESOURCE_IF_NOT_CHANGED + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - @RequestMapping(value = "/resource/pkcs12/{resourceId}/download", method = RequestMethod.GET) + @RequestMapping(value = "/resource/pkcs12/{resourceId}/download", method = RequestMethod.GET, produces = "application/x-pkcs12") @ResponseBody public ResponseEntity downloadPkcs12ResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { + @PathVariable(RESOURCE_ID) String strResourceId, + @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { return downloadResourceIfChanged(ResourceType.PKCS_12, strResourceId, etag); } - @ApiOperation(value = "Download JKS Resource (downloadJksResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Download JKS Resource (downloadJksResourceIfChanged)", + notes = DOWNLOAD_RESOURCE_IF_NOT_CHANGED + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - @RequestMapping(value = "/resource/jks/{resourceId}/download", method = RequestMethod.GET) + @RequestMapping(value = "/resource/jks/{resourceId}/download", method = RequestMethod.GET, produces = "application/x-java-keystore") @ResponseBody public ResponseEntity downloadJksResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { + @PathVariable(RESOURCE_ID) String strResourceId, + @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { return downloadResourceIfChanged(ResourceType.JKS, strResourceId, etag); } - @ApiOperation(value = "Download JS Resource (downloadJsResourceIfChanged)", notes = "Download Resource based on the provided Resource Id or return 304 status code if resource was not changed." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) + @ApiOperation(value = "Download JS Resource (downloadJsResourceIfChanged)", notes = DOWNLOAD_RESOURCE_IF_NOT_CHANGED + AVAILABLE_FOR_ANY_AUTHORIZED_USER) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/resource/js/{resourceId}/download", method = RequestMethod.GET) + @RequestMapping(value = "/resource/js/{resourceId}/download", method = RequestMethod.GET, produces = "application/javascript") @ResponseBody public ResponseEntity downloadJsResourceIfChanged(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) - @PathVariable(RESOURCE_ID) String strResourceId, @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { + @PathVariable(RESOURCE_ID) String strResourceId, + @RequestHeader(name = HttpHeaders.IF_NONE_MATCH, required = false) String etag) throws ThingsboardException { return downloadResourceIfChanged(ResourceType.JS_MODULE, strResourceId, etag); } @@ -211,7 +215,7 @@ public class TbResourceController extends BaseController { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); TbResourceInfoFilter.TbResourceInfoFilterBuilder filter = TbResourceInfoFilter.builder(); filter.tenantId(getTenantId()); - if (StringUtils.isNotEmpty(resourceType)){ + if (StringUtils.isNotEmpty(resourceType)) { filter.resourceType(ResourceType.valueOf(resourceType)); } if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { @@ -277,9 +281,9 @@ public class TbResourceController extends BaseController { if (etag != null) { TbResourceInfo tbResourceInfo = checkResourceInfoId(resourceId, Operation.READ); - if (etag.equals(tbResourceInfo.getHashCode())) { + if (etag.equals(tbResourceInfo.getEtag())) { return ResponseEntity.status(HttpStatus.NOT_MODIFIED) - .eTag(tbResourceInfo.getHashCode()) + .eTag(tbResourceInfo.getEtag()) .build(); } } @@ -293,7 +297,7 @@ public class TbResourceController extends BaseController { .contentLength(resource.contentLength()) .header("Content-Type", type.getMediaType()) .cacheControl(CacheControl.noCache()) - .eTag(tbResource.getHashCode()) + .eTag(tbResource.getEtag()) .body(resource); } } \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java index 97eac85c48..81a06e9344 100644 --- a/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java +++ b/application/src/main/java/org/thingsboard/server/service/resource/DefaultTbResourceService.java @@ -170,7 +170,7 @@ public class DefaultTbResourceService extends AbstractTbEntityService implements resource.setResourceKey(resource.getFileName()); } HashCode hashCode = Hashing.sha256().hashBytes(Base64.getDecoder().decode(resource.getData().getBytes())); - resource.setHashCode(hashCode.toString()); + resource.setEtag(hashCode.toString()); return resourceService.saveResource(resource); } } diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java index 1a8f87713e..6259b3684f 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java @@ -19,9 +19,13 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.HasTenantId; +import org.thingsboard.server.common.data.ResourceType; +import org.thingsboard.server.common.data.TbResource; +import org.thingsboard.server.common.data.TbResourceInfo; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.service.security.model.SecurityUser; @@ -44,6 +48,7 @@ public class CustomerUserPermissions extends AbstractPermissions { put(Resource.RPC, rpcPermissionChecker); put(Resource.DEVICE_PROFILE, profilePermissionChecker); put(Resource.ASSET_PROFILE, profilePermissionChecker); + put(Resource.TB_RESOURCE, customerResourcePermissionChecker); } private static final PermissionChecker customerAlarmPermissionChecker = new PermissionChecker() { @@ -95,6 +100,26 @@ public class CustomerUserPermissions extends AbstractPermissions { }; + private static final PermissionChecker customerResourcePermissionChecker = + new PermissionChecker.GenericPermissionChecker(Operation.READ) { + + @Override + @SuppressWarnings("unchecked") + public boolean hasPermission(SecurityUser user, Operation operation, TbResourceId resourceId, TbResourceInfo resource) { + if (operation != Operation.READ) { + return false; + } + if (resource.getResourceType() == null || !resource.getResourceType().isCustomerAccess()) { + return false; + } + if (resource.getTenantId() == null || resource.getTenantId().isNullUid()) { + return true; + } + return user.getTenantId().equals(resource.getTenantId()); + } + + }; + private static final PermissionChecker customerDashboardPermissionChecker = new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY) { diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 67598b0e83..7f57fbbb3f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -166,6 +166,8 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { private static final String CUSTOMER_USER_PASSWORD = "customer"; protected static final String DIFFERENT_CUSTOMER_USER_EMAIL = "testdifferentcustomer@thingsboard.org"; + + protected static final String DIFFERENT_TENANT_CUSTOMER_USER_EMAIL = "testdifferenttenantcustomer@thingsboard.org"; private static final String DIFFERENT_CUSTOMER_USER_PASSWORD = "diffcustomer"; /** @@ -191,9 +193,13 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected CustomerId customerId; protected TenantId differentTenantId; protected CustomerId differentCustomerId; + + protected CustomerId differentTenantCustomerId; protected UserId customerUserId; protected UserId differentCustomerUserId; + protected UserId differentTenantCustomerUserId; + @SuppressWarnings("rawtypes") private HttpMessageConverter mappingJackson2HttpMessageConverter; @@ -365,7 +371,9 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected Tenant savedDifferentTenant; protected User savedDifferentTenantUser; private Customer savedDifferentCustomer; + private Customer savedDifferentTenantCustomer; protected User differentCustomerUser; + protected User differentTenantCustomerUser; protected void loginDifferentTenant() throws Exception { if (savedDifferentTenant != null) { @@ -407,6 +415,24 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { } } + protected void loginDifferentTenantCustomer() throws Exception { + if (savedDifferentTenantCustomer != null) { + login(savedDifferentTenantCustomer.getEmail(), CUSTOMER_USER_PASSWORD); + } else { + createDifferentTenantCustomer(); + + loginDifferentTenant(); + differentTenantCustomerUser = new User(); + differentTenantCustomerUser.setAuthority(Authority.CUSTOMER_USER); + differentTenantCustomerUser.setTenantId(savedDifferentTenantCustomer.getTenantId()); + differentTenantCustomerUser.setCustomerId(savedDifferentTenantCustomer.getId()); + differentTenantCustomerUser.setEmail(DIFFERENT_TENANT_CUSTOMER_USER_EMAIL); + + differentTenantCustomerUser = createUserAndLogin(differentTenantCustomerUser, DIFFERENT_CUSTOMER_USER_PASSWORD); + differentTenantCustomerUserId = differentTenantCustomerUser.getId(); + } + } + protected void createDifferentCustomer() throws Exception { loginTenantAdmin(); @@ -419,6 +445,18 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { resetTokens(); } + protected void createDifferentTenantCustomer() throws Exception { + loginDifferentTenant(); + + Customer customer = new Customer(); + customer.setTitle("Different tenant customer"); + savedDifferentTenantCustomer = doPost("/api/customer", customer, Customer.class); + Assert.assertNotNull(savedDifferentTenantCustomer); + differentTenantCustomerId = savedDifferentTenantCustomer.getId(); + + resetTokens(); + } + protected void deleteDifferentTenant() throws Exception { if (savedDifferentTenant != null) { loginSysAdmin(); diff --git a/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java index 111a08d571..b4735519a5 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbResourceControllerTest.java @@ -526,7 +526,6 @@ public class TbResourceControllerTest extends AbstractControllerTest { .andExpect(status().isNotModified()); } - @Ignore @Test public void testDownloadTbResourceIfChangedAsPublicCustomer() throws Exception { loginTenantAdmin(); @@ -571,6 +570,25 @@ public class TbResourceControllerTest extends AbstractControllerTest { .andExpect(status().isNotModified()); } + @Test + public void testDownloadTbResourceIfChangedAsCustomerOfDifferentTenant() throws Exception { + loginTenantAdmin(); + Mockito.reset(tbClusterService, auditLogService); + + TbResource resource = new TbResource(); + resource.setResourceType(ResourceType.JS_MODULE); + resource.setTitle("Js resource"); + resource.setFileName(JS_TEST_FILE_NAME); + resource.setData(TEST_DATA); + + TbResource savedResource = save(resource); + + loginDifferentTenant(); + loginDifferentTenantCustomer(); + doGet("/api/resource/js/" + savedResource.getId().getId().toString() + "/download") + .andExpect(status().isForbidden()); + } + private TbResource save(TbResource tbResource) throws Exception { return doPostWithTypedResponse("/api/resource", tbResource, new TypeReference<>(){}); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java index 81be6a1e41..3c2b9a4bc0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ResourceType.java @@ -15,19 +15,21 @@ */ package org.thingsboard.server.common.data; +import lombok.Getter; + public enum ResourceType { - LWM2M_MODEL("application/xml"), - JKS("application/x-java-keystore"), - PKCS_12("application/x-pkcs12"), - JS_MODULE("application/javascript"); + LWM2M_MODEL("application/xml", false), + JKS("application/x-java-keystore", false), + PKCS_12("application/x-pkcs12", false), + JS_MODULE("application/javascript", true); + @Getter private final String mediaType; + @Getter + private final boolean customerAccess; - ResourceType(String mediaType) { + ResourceType(String mediaType, boolean customerAccess) { this.mediaType = mediaType; - } - - public String getMediaType() { - return mediaType; + this.customerAccess = customerAccess; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java index 1d6f7ca21d..8b82db196a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java @@ -75,7 +75,7 @@ public class TbResource extends TbResourceInfo { builder.append(", data="); builder.append(data); builder.append(", hashCode="); - builder.append(getHashCode()); + builder.append(getEtag()); builder.append("]"); return builder.toString(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java index 671cd65924..af3c71f226 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java @@ -48,8 +48,8 @@ public class TbResourceInfo extends BaseData implements HasName, H private String resourceKey; @ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", accessMode = ApiModelProperty.AccessMode.READ_ONLY) private String searchText; - @ApiModelProperty(position = 8, value = "Resource hash code.", example = "33a64df551425fcc55e4d42a148795d9f25f89d4", accessMode = ApiModelProperty.AccessMode.READ_ONLY) - private String hashCode; + @ApiModelProperty(position = 8, value = "Resource etag.", example = "33a64df551425fcc55e4d42a148795d9f25f89d4", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + private String etag; public TbResourceInfo() { super(); @@ -66,7 +66,7 @@ public class TbResourceInfo extends BaseData implements HasName, H this.resourceType = resourceInfo.getResourceType(); this.resourceKey = resourceInfo.getResourceKey(); this.searchText = resourceInfo.getSearchText(); - this.hashCode = resourceInfo.getHashCode(); + this.etag = resourceInfo.getEtag(); } @ApiModelProperty(position = 1, value = "JSON object with the Resource Id. " + @@ -111,7 +111,7 @@ public class TbResourceInfo extends BaseData implements HasName, H builder.append(", resourceKey="); builder.append(resourceKey); builder.append(", hashCode="); - builder.append(hashCode); + builder.append(etag); builder.append("]"); return builder.toString(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 68123b22c4..ccbd029595 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -480,7 +480,7 @@ public class ModelConstants { public static final String RESOURCE_TITLE_COLUMN = TITLE_PROPERTY; public static final String RESOURCE_FILE_NAME_COLUMN = "file_name"; public static final String RESOURCE_DATA_COLUMN = "data"; - public static final String RESOURCE_HASH_CODE_COLUMN = "hash_code"; + public static final String RESOURCE_ETAG_COLUMN = "etag"; /** * Ota Package constants. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java index bfd26a6290..4fbc50fd69 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java @@ -31,7 +31,7 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_DATA_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_FILE_NAME_COLUMN; -import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_HASH_CODE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_ETAG_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_KEY_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TENANT_ID_COLUMN; @@ -66,8 +66,8 @@ public class TbResourceEntity extends BaseSqlEntity implements BaseE @Column(name = RESOURCE_DATA_COLUMN) private String data; - @Column(name = RESOURCE_HASH_CODE_COLUMN) - private String hashCode; + @Column(name = RESOURCE_ETAG_COLUMN) + private String etag; public TbResourceEntity() { } @@ -86,7 +86,7 @@ public class TbResourceEntity extends BaseSqlEntity implements BaseE this.searchText = resource.getSearchText(); this.fileName = resource.getFileName(); this.data = resource.getData(); - this.hashCode = resource.getHashCode(); + this.etag = resource.getEtag(); } @Override @@ -100,7 +100,7 @@ public class TbResourceEntity extends BaseSqlEntity implements BaseE resource.setSearchText(searchText); resource.setFileName(fileName); resource.setData(data); - resource.setHashCode(hashCode); + resource.setEtag(etag); return resource; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java index cb2dcf3133..e8504bc388 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java @@ -29,7 +29,7 @@ import javax.persistence.Entity; import javax.persistence.Table; import java.util.UUID; -import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_HASH_CODE_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_ETAG_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_KEY_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_TENANT_ID_COLUMN; @@ -58,7 +58,7 @@ public class TbResourceInfoEntity extends BaseSqlEntity implemen @Column(name = SEARCH_TEXT_PROPERTY) private String searchText; - @Column(name = RESOURCE_HASH_CODE_COLUMN) + @Column(name = RESOURCE_ETAG_COLUMN) private String hashCode; public TbResourceInfoEntity() { @@ -74,7 +74,7 @@ public class TbResourceInfoEntity extends BaseSqlEntity implemen this.resourceType = resource.getResourceType().name(); this.resourceKey = resource.getResourceKey(); this.searchText = resource.getSearchText(); - this.hashCode = resource.getHashCode(); + this.hashCode = resource.getEtag(); } @Override @@ -86,7 +86,7 @@ public class TbResourceInfoEntity extends BaseSqlEntity implemen resource.setResourceType(ResourceType.valueOf(resourceType)); resource.setResourceKey(resourceKey); resource.setSearchText(searchText); - resource.setHashCode(hashCode); + resource.setEtag(hashCode); return resource; } } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 62231e6995..3b4861e015 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -697,7 +697,7 @@ CREATE TABLE IF NOT EXISTS resource ( search_text varchar(255), file_name varchar(255) NOT NULL, data varchar, - hash_code varchar, + etag varchar, CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key) ); From 59d21eb9d737abe73b8c276c9b9d15421b8eb580 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 8 Jun 2023 17:59:08 +0300 Subject: [PATCH 158/207] Simplify permission check --- .../service/security/permission/CustomerUserPermissions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java index 6259b3684f..bcd1c287c4 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java @@ -101,7 +101,7 @@ public class CustomerUserPermissions extends AbstractPermissions { }; private static final PermissionChecker customerResourcePermissionChecker = - new PermissionChecker.GenericPermissionChecker(Operation.READ) { + new PermissionChecker() { @Override @SuppressWarnings("unchecked") From b77078c24e3b5a01865394826e81cb4ba38e3f49 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 8 Jun 2023 18:15:56 +0300 Subject: [PATCH 159/207] Notifications deduplication improvements --- .../ruleChain/RuleEngineComponentActor.java | 2 +- .../NotificationRuleController.java | 2 +- .../service/action/EntityActionService.java | 8 +- .../DefaultTbApiUsageStateService.java | 2 +- .../DefaultNotificationRuleProcessor.java | 59 +-------- .../cache/DefaultNotificationRulesCache.java | 2 +- .../rule/cache/NotificationRulesCache.java | 2 +- .../AlarmAssignmentTriggerProcessor.java | 8 +- .../trigger/AlarmCommentTriggerProcessor.java | 6 +- .../rule/trigger/AlarmTriggerProcessor.java | 10 +- .../ApiUsageLimitTriggerProcessor.java | 6 +- .../DeviceActivityTriggerProcessor.java | 8 +- .../EntitiesLimitTriggerProcessor.java | 6 +- .../trigger/EntityActionTriggerProcessor.java | 6 +- .../NewPlatformVersionTriggerProcessor.java | 6 +- .../NotificationRuleTriggerProcessor.java | 6 +- ...mponentLifecycleEventTriggerProcessor.java | 6 +- .../queue/DefaultTbCoreConsumerService.java | 2 +- .../state/DefaultDeviceStateService.java | 2 +- .../impl/NotificationRuleExportService.java | 6 +- .../impl/NotificationRuleImportService.java | 8 +- .../DefaultAlarmSubscriptionService.java | 2 +- .../service/update/DefaultUpdateService.java | 2 +- .../src/main/resources/thingsboard.yml | 6 +- .../AbstractNotificationApiTest.java | 2 +- .../notification/NotificationRuleApiTest.java | 28 ++--- .../NotificationTargetApiTest.java | 2 +- .../notification/NotificationRuleService.java | 2 +- .../notification/rule/NotificationRule.java | 4 +- .../NotificationRuleRecipientsConfig.java | 2 +- .../rule}/trigger/AlarmAssignmentTrigger.java | 4 +- .../rule}/trigger/AlarmCommentTrigger.java | 4 +- .../rule}/trigger/AlarmTrigger.java | 4 +- .../rule}/trigger/ApiUsageLimitTrigger.java | 4 +- .../rule}/trigger/DeviceActivityTrigger.java | 4 +- .../rule}/trigger/EntitiesLimitTrigger.java | 4 +- .../rule}/trigger/EntityActionTrigger.java | 4 +- .../trigger/NewPlatformVersionTrigger.java | 4 +- .../trigger/NotificationRuleTrigger.java | 4 +- ...eEngineComponentLifecycleEventTrigger.java | 4 +- ...signmentNotificationRuleTriggerConfig.java | 2 +- ...mCommentNotificationRuleTriggerConfig.java | 2 +- .../AlarmNotificationRuleTriggerConfig.java | 2 +- ...ageLimitNotificationRuleTriggerConfig.java | 2 +- ...ActivityNotificationRuleTriggerConfig.java | 2 +- ...iesLimitNotificationRuleTriggerConfig.java | 2 +- ...tyActionNotificationRuleTriggerConfig.java | 2 +- ...mVersionNotificationRuleTriggerConfig.java | 2 +- .../NotificationRuleTriggerConfig.java | 2 +- .../NotificationRuleTriggerType.java | 2 +- ...cleEventNotificationRuleTriggerConfig.java | 2 +- .../NotificationRuleProcessor.java | 2 +- ...faultNotificationDeduplicationService.java | 114 ++++++++++++++++++ .../NotificationDeduplicationService.java} | 14 ++- .../RemoteNotificationRuleProcessor.java | 67 +--------- .../dao/model/sql/NotificationRuleEntity.java | 4 +- .../DefaultNotificationRuleService.java | 2 +- .../notification/DefaultNotifications.java | 26 ++-- .../dao/notification/NotificationRuleDao.java | 2 +- .../notification/JpaNotificationRuleDao.java | 2 +- .../NotificationRuleRepository.java | 2 +- 61 files changed, 262 insertions(+), 248 deletions(-) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/AlarmAssignmentTrigger.java (93%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/AlarmCommentTrigger.java (93%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/AlarmTrigger.java (92%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/ApiUsageLimitTrigger.java (92%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/DeviceActivityTrigger.java (93%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/EntitiesLimitTrigger.java (92%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/EntityActionTrigger.java (93%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/NewPlatformVersionTrigger.java (94%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/NotificationRuleTrigger.java (92%) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/RuleEngineComponentLifecycleEventTrigger.java (93%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/AlarmAssignmentNotificationRuleTriggerConfig.java (99%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/AlarmCommentNotificationRuleTriggerConfig.java (99%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/AlarmNotificationRuleTriggerConfig.java (99%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/ApiUsageLimitNotificationRuleTriggerConfig.java (99%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/DeviceActivityNotificationRuleTriggerConfig.java (99%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/EntitiesLimitNotificationRuleTriggerConfig.java (99%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/EntityActionNotificationRuleTriggerConfig.java (99%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/NewPlatformVersionNotificationRuleTriggerConfig.java (98%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/NotificationRuleTriggerConfig.java (99%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/NotificationRuleTriggerType.java (98%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig.java (99%) create mode 100644 common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java rename common/{data/src/main/java/org/thingsboard/server/common/data/notification/settings/TriggerTypeConfig.java => queue/src/main/java/org/thingsboard/server/queue/notification/NotificationDeduplicationService.java} (59%) diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleEngineComponentActor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleEngineComponentActor.java index e1918466a8..42a78b7965 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleEngineComponentActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleEngineComponentActor.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.msg.TbActorStopReason; -import org.thingsboard.server.common.msg.notification.trigger.RuleEngineComponentLifecycleEventTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventTrigger; public abstract class RuleEngineComponentActor> extends ComponentActor { diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java index ccf2124113..2afb67a8bd 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java @@ -34,7 +34,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.NotificationRuleId; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; diff --git a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java index 99b508a12d..e068cd4d23 100644 --- a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java +++ b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java @@ -43,10 +43,10 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.msg.notification.trigger.AlarmAssignmentTrigger; -import org.thingsboard.server.common.msg.notification.trigger.AlarmCommentTrigger; -import org.thingsboard.server.common.msg.notification.trigger.EntitiesLimitTrigger; -import org.thingsboard.server.common.msg.notification.trigger.EntityActionTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionTrigger; import org.thingsboard.server.dao.audit.AuditLogService; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java index 7e2719598c..ef6e4fa0bf 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java @@ -48,7 +48,7 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; -import org.thingsboard.server.common.msg.notification.trigger.ApiUsageLimitTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.ApiUsageLimitTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java index 71a59026a2..93d89fa0b1 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java @@ -16,17 +16,12 @@ package org.thingsboard.server.service.notification.rule; import lombok.RequiredArgsConstructor; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cache.Cache; -import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Lazy; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.NotificationCenter; -import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.NotificationRequestId; @@ -37,61 +32,47 @@ import org.thingsboard.server.common.data.notification.NotificationRequestConfig import org.thingsboard.server.common.data.notification.NotificationRequestStatus; import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.rule.NotificationRule; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.settings.TriggerTypeConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTrigger; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; import org.thingsboard.server.queue.discovery.PartitionService; +import org.thingsboard.server.queue.notification.NotificationDeduplicationService; import org.thingsboard.server.service.executors.NotificationExecutorService; import org.thingsboard.server.service.notification.rule.cache.NotificationRulesCache; import org.thingsboard.server.service.notification.rule.trigger.NotificationRuleTriggerProcessor; -import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @Service @RequiredArgsConstructor -@ConfigurationProperties(prefix = "notification-system.rules") @Slf4j @SuppressWarnings({"rawtypes", "unchecked"}) public class DefaultNotificationRuleProcessor implements NotificationRuleProcessor { private final NotificationRulesCache notificationRulesCache; private final NotificationRequestService notificationRequestService; + private final NotificationDeduplicationService deduplicationService; private final PartitionService partitionService; private final RateLimitService rateLimitService; @Autowired @Lazy private NotificationCenter notificationCenter; private final NotificationExecutorService notificationExecutor; - private final CacheManager cacheManager; - private Cache sentNotifications; - @Setter - private Map triggerTypesConfigs; private final Map triggerProcessors = new EnumMap<>(NotificationRuleTriggerType.class); - @PostConstruct - private void init() { - sentNotifications = cacheManager.getCache(CacheConstants.SENT_NOTIFICATIONS_CACHE); - if (sentNotifications == null) { - throw new IllegalStateException("Sent notifications cache is not set up"); - } - } - @Override public void process(NotificationRuleTrigger trigger) { NotificationRuleTriggerType triggerType = trigger.getType(); @@ -104,7 +85,7 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess } if (trigger.deduplicate()) { enabledRules = new ArrayList<>(enabledRules); - enabledRules.removeIf(rule -> alreadySent(rule, trigger)); + enabledRules.removeIf(rule -> deduplicationService.alreadyProcessed(trigger, rule)); } final List rules = enabledRules; notificationExecutor.submit(() -> { @@ -199,34 +180,6 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess return triggerProcessors.get(triggerConfig.getTriggerType()).constructNotificationInfo(trigger); } - private boolean alreadySent(NotificationRule rule, NotificationRuleTrigger trigger) { - String deduplicationKey = getDeduplicationKey(trigger, rule); - - boolean alreadySent = false; - Long lastSentTs = sentNotifications.get(deduplicationKey, Long.class); - if (lastSentTs != null) { - long deduplicationDuration = Optional.ofNullable(triggerTypesConfigs) - .map(triggerTypes -> triggerTypes.get(trigger.getType())) - .map(TriggerTypeConfig::getDeduplicationDuration) - .orElseGet(trigger::getDefaultDeduplicationDuration); - long passed = System.currentTimeMillis() - lastSentTs; - log.trace("Deduplicating trigger {} for rule '{}' by key '{}'. Deduplication duration: {} ms, passed: {} ms", - trigger.getType(), rule.getName(), deduplicationKey, deduplicationDuration, passed); - if (deduplicationDuration == 0 || passed <= deduplicationDuration) { - alreadySent = true; - } - } - if (!alreadySent) { - lastSentTs = System.currentTimeMillis(); - } - sentNotifications.put(deduplicationKey, lastSentTs); - return alreadySent; - } - - public static String getDeduplicationKey(NotificationRuleTrigger trigger, NotificationRule rule) { - return String.join("_", trigger.getDeduplicationKey(), rule.getDeduplicationKey()); - } - @EventListener(ComponentLifecycleMsg.class) public void onNotificationRuleDeleted(ComponentLifecycleMsg componentLifecycleMsg) { if (componentLifecycleMsg.getEvent() != ComponentLifecycleEvent.DELETED || diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java index a43ed59efa..d8ac13364b 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java @@ -24,7 +24,7 @@ import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.rule.NotificationRule; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.dao.notification.NotificationRuleService; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/NotificationRulesCache.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/NotificationRulesCache.java index 2a1054b352..bcfa7d0120 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/NotificationRulesCache.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/NotificationRulesCache.java @@ -17,7 +17,7 @@ package org.thingsboard.server.service.notification.rule.cache; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.rule.NotificationRule; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java index eca258aecc..dba5fd8de4 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java @@ -22,10 +22,10 @@ import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.notification.info.AlarmAssignmentNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig.Action; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.AlarmAssignmentTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig.Action; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentTrigger; import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java index 70024d6e09..ef742922b3 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.notification.info.AlarmCommentNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.AlarmCommentTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmCommentNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentTrigger; import org.thingsboard.server.dao.entity.EntityService; import static org.apache.commons.collections.CollectionUtils.isEmpty; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java index c32ed26854..d69d502aa2 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java @@ -22,11 +22,11 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; import org.thingsboard.server.common.data.notification.info.AlarmNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig.AlarmAction; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig.ClearRule; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.AlarmTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig.AlarmAction; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig.ClearRule; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmTrigger; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/ApiUsageLimitTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/ApiUsageLimitTriggerProcessor.java index 4e66a7905c..112fe2af7a 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/ApiUsageLimitTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/ApiUsageLimitTriggerProcessor.java @@ -19,9 +19,9 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.notification.info.ApiUsageLimitNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.ApiUsageLimitNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.ApiUsageLimitTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.ApiUsageLimitNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.ApiUsageLimitTrigger; import org.thingsboard.server.dao.tenant.TenantService; import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java index 3188eeabb1..729ad7f8da 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java @@ -23,10 +23,10 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.info.DeviceActivityNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.DeviceActivityTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityTrigger; import org.thingsboard.server.service.profile.TbDeviceProfileCache; @Service diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntitiesLimitTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntitiesLimitTriggerProcessor.java index 95ace87653..9539b42a43 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntitiesLimitTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntitiesLimitTriggerProcessor.java @@ -19,10 +19,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.notification.info.EntitiesLimitNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EntitiesLimitNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; -import org.thingsboard.server.common.msg.notification.trigger.EntitiesLimitTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitTrigger; import org.thingsboard.server.dao.entity.EntityCountService; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TenantService; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntityActionTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntityActionTriggerProcessor.java index ea4902fb05..bc290fa978 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntityActionTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EntityActionTriggerProcessor.java @@ -20,9 +20,9 @@ import org.thingsboard.server.common.data.HasCustomerId; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.notification.info.EntityActionNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.EntityActionTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionTrigger; import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NewPlatformVersionTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NewPlatformVersionTriggerProcessor.java index 639378ad72..aeec1a9b39 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NewPlatformVersionTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NewPlatformVersionTriggerProcessor.java @@ -20,9 +20,9 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.UpdateMessage; import org.thingsboard.server.common.data.notification.info.NewPlatformVersionNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.NewPlatformVersionTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger; @Service @RequiredArgsConstructor diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NotificationRuleTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NotificationRuleTriggerProcessor.java index fe7fb82ee5..67a8d3d701 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NotificationRuleTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/NotificationRuleTriggerProcessor.java @@ -16,9 +16,9 @@ package org.thingsboard.server.service.notification.rule.trigger; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger; public interface NotificationRuleTriggerProcessor { diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineComponentLifecycleEventTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineComponentLifecycleEventTriggerProcessor.java index 6e37db83ef..8aac7ffd66 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineComponentLifecycleEventTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RuleEngineComponentLifecycleEventTriggerProcessor.java @@ -23,10 +23,10 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.notification.info.RuleEngineComponentLifecycleEventNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; -import org.thingsboard.server.common.msg.notification.trigger.RuleEngineComponentLifecycleEventTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.queue.discovery.PartitionService; diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java index 182fce1c48..dc24d6df33 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java @@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.rpc.RpcError; import org.thingsboard.server.common.msg.MsgType; import org.thingsboard.server.common.msg.TbActorMsg; -import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index 337d607fac..554359fd6d 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -63,7 +63,7 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.msg.notification.trigger.DeviceActivityTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java index 0906fb83ef..a2b9c54403 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java @@ -28,9 +28,9 @@ import org.thingsboard.server.common.data.notification.rule.DefaultNotificationR import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleRecipientsConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.sync.ie.EntityExportData; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.sync.vc.data.EntitiesExportCtx; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/NotificationRuleImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/NotificationRuleImportService.java index a7d7670c8c..9ace036ee6 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/NotificationRuleImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/NotificationRuleImportService.java @@ -32,10 +32,10 @@ import org.thingsboard.server.common.data.notification.rule.DefaultNotificationR import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleRecipientsConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.data.sync.ie.EntityExportData; import org.thingsboard.server.dao.notification.NotificationRuleService; diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java index e7f2a5a66f..1603d33bfd 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java @@ -47,7 +47,7 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.AlarmData; import org.thingsboard.server.common.data.query.AlarmDataQuery; -import org.thingsboard.server.common.msg.notification.trigger.AlarmTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmTrigger; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.dao.alarm.AlarmOperationResult; diff --git a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java index 587d86af32..f5e3daf05d 100644 --- a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java @@ -28,7 +28,7 @@ import org.springframework.web.client.RestTemplate; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.UpdateMessage; -import org.thingsboard.server.common.msg.notification.trigger.NewPlatformVersionTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbCoreComponent; diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 392587c869..77300b3f2f 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -1262,10 +1262,8 @@ vc: notification_system: thread_pool_size: "${TB_NOTIFICATION_SYSTEM_THREAD_POOL_SIZE:10}" rules: - trigger_types_configs: - NEW_PLATFORM_VERSION: - # In milliseconds, infinitely by default - deduplication_duration: "${NEW_PLATFORM_VERSION_NOTIFICATION_RULE_DEDUPLICATION_DURATION:0}" + # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' + deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:NEW_PLATFORM_VERSION:0;}" management: endpoints: diff --git a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java index f45882e416..fb7675bd9e 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java @@ -40,7 +40,7 @@ import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.rule.DefaultNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.settings.NotificationSettings; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig; diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java index 6c4413d1e7..faa1e1e69c 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java @@ -61,15 +61,15 @@ import org.thingsboard.server.common.data.notification.rule.DefaultNotificationR import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig.AlarmAction; -import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmCommentNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig.AlarmAction; +import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EntitiesLimitNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.page.PageData; @@ -81,7 +81,7 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.msg.notification.trigger.NewPlatformVersionTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger; import org.thingsboard.server.dao.notification.DefaultNotifications; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.rule.RuleChainService; @@ -109,10 +109,10 @@ import static org.assertj.core.api.Assertions.offset; import static org.assertj.core.api.InstanceOfAssertFactories.type; import static org.awaitility.Awaitility.await; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig.Action.ASSIGNED; -import static org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig.Action.UNASSIGNED; -import static org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent.ACTIVE; -import static org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent.INACTIVE; +import static org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig.Action.ASSIGNED; +import static org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig.Action.UNASSIGNED; +import static org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent.ACTIVE; +import static org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent.INACTIVE; @DaoSqlTest @TestPropertySource(properties = { diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java index 480bbf939b..76b68bb9bf 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java @@ -24,7 +24,7 @@ import org.springframework.test.web.servlet.ResultMatcher; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; -import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.platform.AllUsersFilter; import org.thingsboard.server.common.data.notification.targets.platform.CustomerUsersFilter; diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationRuleService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationRuleService.java index bd23f1c48d..d1b7513031 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationRuleService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationRuleService.java @@ -19,7 +19,7 @@ import org.thingsboard.server.common.data.id.NotificationRuleId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java index c88ade5bb1..e7cb4f8c4f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java @@ -26,8 +26,8 @@ import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.id.NotificationRuleId; import org.thingsboard.server.common.data.id.NotificationTemplateId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRuleRecipientsConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRuleRecipientsConfig.java index d31ec098ca..c5bcf98302 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRuleRecipientsConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRuleRecipientsConfig.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; import lombok.Data; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import javax.validation.constraints.NotNull; import java.io.Serializable; diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmAssignmentTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentTrigger.java similarity index 93% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmAssignmentTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentTrigger.java index 98ed43f886..11d24386bc 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmAssignmentTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentTrigger.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Data @Builder diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmCommentTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentTrigger.java similarity index 93% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmCommentTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentTrigger.java index d0b3bdd5de..65ad9c9619 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmCommentTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentTrigger.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; @@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Data @Builder diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmTrigger.java similarity index 92% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmTrigger.java index b395ba9ebe..674355150f 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/AlarmTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmTrigger.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.alarm.AlarmApiCallResult; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Data @Builder diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/ApiUsageLimitTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/ApiUsageLimitTrigger.java similarity index 92% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/ApiUsageLimitTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/ApiUsageLimitTrigger.java index f21d3077ca..323f2b275f 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/ApiUsageLimitTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/ApiUsageLimitTrigger.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; @@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.ApiUsageRecordState; import org.thingsboard.server.common.data.ApiUsageStateValue; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Data @Builder diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/DeviceActivityTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityTrigger.java similarity index 93% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/DeviceActivityTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityTrigger.java index b426b6674b..0c0139410e 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/DeviceActivityTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityTrigger.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; @@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Data @Builder diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntitiesLimitTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitTrigger.java similarity index 92% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntitiesLimitTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitTrigger.java index e6ce143fd0..3222e3fc6d 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntitiesLimitTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitTrigger.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Data @Builder diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntityActionTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntityActionTrigger.java similarity index 93% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntityActionTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntityActionTrigger.java index 47d1789fec..aaf61ab0bc 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/EntityActionTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntityActionTrigger.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Data @Builder diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NewPlatformVersionTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NewPlatformVersionTrigger.java similarity index 94% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NewPlatformVersionTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NewPlatformVersionTrigger.java index 2bb88a708b..9776bfb575 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NewPlatformVersionTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NewPlatformVersionTrigger.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.UpdateMessage; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Data @Builder diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NotificationRuleTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTrigger.java similarity index 92% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NotificationRuleTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTrigger.java index 0cfc87a4df..2aac6fe75e 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/NotificationRuleTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTrigger.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import java.io.Serializable; diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RuleEngineComponentLifecycleEventTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RuleEngineComponentLifecycleEventTrigger.java similarity index 93% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RuleEngineComponentLifecycleEventTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RuleEngineComponentLifecycleEventTrigger.java index 56f4298b29..f1509eb2dc 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RuleEngineComponentLifecycleEventTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RuleEngineComponentLifecycleEventTrigger.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmAssignmentNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmAssignmentNotificationRuleTriggerConfig.java index 59ad9e5316..ce9ade2e6f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmAssignmentNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmCommentNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmCommentNotificationRuleTriggerConfig.java index c34127b611..f0d8a7ef15 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmCommentNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmCommentNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmNotificationRuleTriggerConfig.java index 6118e9da00..318a99ffdd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/AlarmNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/ApiUsageLimitNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/ApiUsageLimitNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/ApiUsageLimitNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/ApiUsageLimitNotificationRuleTriggerConfig.java index d5ce9dff68..ec49e3828a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/ApiUsageLimitNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/ApiUsageLimitNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/DeviceActivityNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/DeviceActivityNotificationRuleTriggerConfig.java index 8deeada7c0..7777955912 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/DeviceActivityNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EntitiesLimitNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EntitiesLimitNotificationRuleTriggerConfig.java index a40ddfb081..0dfd8d0cc4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EntitiesLimitNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntityActionNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EntityActionNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntityActionNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EntityActionNotificationRuleTriggerConfig.java index 3a627a9e56..ed61d5eb94 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntityActionNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EntityActionNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NewPlatformVersionNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NewPlatformVersionNotificationRuleTriggerConfig.java similarity index 98% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NewPlatformVersionNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NewPlatformVersionNotificationRuleTriggerConfig.java index 230be3b9d5..ebec3967d0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NewPlatformVersionNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NewPlatformVersionNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.Data; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerConfig.java index b0eec28858..9e6e757afd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerType.java similarity index 98% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerType.java index dff86f4ba1..3166c337e8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerType.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.Getter; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig.java index c28e190cc9..005d86ac6f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/NotificationRuleProcessor.java b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/NotificationRuleProcessor.java index 380773c1b0..8516a50b2f 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/NotificationRuleProcessor.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/notification/NotificationRuleProcessor.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.msg.notification; -import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger; public interface NotificationRuleProcessor { diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java b/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java new file mode 100644 index 0000000000..a233accf71 --- /dev/null +++ b/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java @@ -0,0 +1,114 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.queue.notification; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.stereotype.Service; +import org.springframework.util.ConcurrentReferenceHashMap; +import org.thingsboard.server.common.data.CacheConstants; +import org.thingsboard.server.common.data.notification.rule.NotificationRule; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.queue.util.PropertyUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; + +import static org.springframework.util.ConcurrentReferenceHashMap.ReferenceType.SOFT; + +@Service +@RequiredArgsConstructor +@Slf4j +public class DefaultNotificationDeduplicationService implements NotificationDeduplicationService { + + private Map deduplicationDurations; + + private final CacheManager cacheManager; + private final ConcurrentMap localCache = new ConcurrentReferenceHashMap<>(16, SOFT); + + @Override + public boolean alreadyProcessed(NotificationRuleTrigger trigger) { + String deduplicationKey = trigger.getDeduplicationKey(); + return alreadyProcessed(trigger, deduplicationKey, true); + } + + @Override + public boolean alreadyProcessed(NotificationRuleTrigger trigger, NotificationRule rule) { + String deduplicationKey = getDeduplicationKey(trigger, rule); + return alreadyProcessed(trigger, deduplicationKey, false); + } + + private boolean alreadyProcessed(NotificationRuleTrigger trigger, String deduplicationKey, boolean onlyLocalCache) { + Long lastProcessedTs = localCache.get(deduplicationKey); + if (lastProcessedTs == null && !onlyLocalCache) { + Cache externalCache = cacheManager.getCache(CacheConstants.SENT_NOTIFICATIONS_CACHE); + if (externalCache != null) { + lastProcessedTs = externalCache.get(deduplicationKey, Long.class); + } else { + log.warn("Sent notifications cache is not set up"); + } + } + + boolean alreadyProcessed = false; + if (lastProcessedTs != null) { + long deduplicationDuration = getDeduplicationDuration(trigger); + long passed = System.currentTimeMillis() - lastProcessedTs; + log.trace("Deduplicating trigger {} by key '{}'. Deduplication duration: {} ms, passed: {} ms", + trigger.getType(), deduplicationKey, deduplicationDuration, passed); + if (deduplicationDuration == 0 || passed <= deduplicationDuration) { + alreadyProcessed = true; + } + } + + if (!alreadyProcessed) { + lastProcessedTs = System.currentTimeMillis(); + } + localCache.put(deduplicationKey, lastProcessedTs); + if (!onlyLocalCache) { + Cache externalCache = cacheManager.getCache(CacheConstants.SENT_NOTIFICATIONS_CACHE); + if (externalCache != null) { + externalCache.put(deduplicationKey, lastProcessedTs); + } + } + return alreadyProcessed; + } + + public static String getDeduplicationKey(NotificationRuleTrigger trigger, NotificationRule rule) { + return String.join("_", trigger.getDeduplicationKey(), rule.getDeduplicationKey()); + } + + private long getDeduplicationDuration(NotificationRuleTrigger trigger) { + return deduplicationDurations.computeIfAbsent(trigger.getType(), triggerType -> { + return trigger.getDefaultDeduplicationDuration(); + }); + } + + @Autowired + public void setDeduplicationDurations(@Value("${notification_system.rules.deduplication_durations:}") + String deduplicationDurationsStr) { + this.deduplicationDurations = new HashMap<>(); + PropertyUtils.getProps(deduplicationDurationsStr).forEach((triggerType, duration) -> { + this.deduplicationDurations.put(NotificationRuleTriggerType.valueOf(triggerType), Long.parseLong(duration)); + }); + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/TriggerTypeConfig.java b/common/queue/src/main/java/org/thingsboard/server/queue/notification/NotificationDeduplicationService.java similarity index 59% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/TriggerTypeConfig.java rename to common/queue/src/main/java/org/thingsboard/server/queue/notification/NotificationDeduplicationService.java index 6991bb1277..3ccc98ecb6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/TriggerTypeConfig.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/notification/NotificationDeduplicationService.java @@ -13,11 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.settings; +package org.thingsboard.server.queue.notification; -import lombok.Data; +import org.thingsboard.server.common.data.notification.rule.NotificationRule; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger; + +public interface NotificationDeduplicationService { + + boolean alreadyProcessed(NotificationRuleTrigger trigger); + + boolean alreadyProcessed(NotificationRuleTrigger trigger, NotificationRule rule); -@Data -public class TriggerTypeConfig { - private long deduplicationDuration; } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java b/common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java index 617fdbb50e..5304056a88 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java @@ -19,13 +19,9 @@ import com.google.protobuf.ByteString; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Service; -import org.springframework.util.ConcurrentReferenceHashMap; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.settings.TriggerTypeConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.msg.notification.trigger.NotificationRuleTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.gen.transport.TransportProtos; @@ -35,35 +31,27 @@ import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.util.DataDecodingEncodingService; -import java.util.EnumMap; -import java.util.Map; import java.util.UUID; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; - -import static org.springframework.util.ConcurrentReferenceHashMap.ReferenceType.SOFT; @Service @ConditionalOnMissingBean(value = NotificationRuleProcessor.class, ignored = RemoteNotificationRuleProcessor.class) -@ConfigurationProperties(prefix = "notification-system.rules") @RequiredArgsConstructor @Slf4j public class RemoteNotificationRuleProcessor implements NotificationRuleProcessor { + private final NotificationDeduplicationService deduplicationService; private final TbQueueProducerProvider producerProvider; private final NotificationsTopicService notificationsTopicService; private final PartitionService partitionService; private final DataDecodingEncodingService encodingService; - private Map triggerTypesConfigs; - private final ConcurrentMap submittedTriggers = new ConcurrentReferenceHashMap<>(16, SOFT); - @Override public void process(NotificationRuleTrigger trigger) { - if (trigger.deduplicate() && alreadySubmitted(trigger)) { - return; - } try { + if (trigger.deduplicate() && deduplicationService.alreadyProcessed(trigger)) { + return; + } + log.debug("Submitting notification rule trigger: {}", trigger); TransportProtos.NotificationRuleProcessorMsg.Builder msg = TransportProtos.NotificationRuleProcessorMsg.newBuilder() .setTrigger(ByteString.copyFrom(encodingService.encode(trigger))); @@ -80,47 +68,4 @@ public class RemoteNotificationRuleProcessor implements NotificationRuleProcesso } } - private boolean alreadySubmitted(NotificationRuleTrigger trigger) { - String deduplicationKey = trigger.getDeduplicationKey(); - - AtomicBoolean alreadySubmitted = new AtomicBoolean(false); - submittedTriggers.compute(deduplicationKey, (key, lastSubmittedTs) -> { - long currentTs = System.currentTimeMillis(); - if (lastSubmittedTs == null) { - return currentTs; - } else { - long deduplicationDuration = getDeduplicationDuration(trigger); - long passed = currentTs - lastSubmittedTs; - if (deduplicationDuration == 0 || passed <= deduplicationDuration) { - log.trace("Notification rule trigger {} was already submitted {} ms ago, deduplication duration is {} ms. Key: '{}'", - trigger.getType(), passed, deduplicationDuration, deduplicationKey); - alreadySubmitted.set(true); - return lastSubmittedTs; - } else { - return currentTs; - } - } - }); - return alreadySubmitted.get(); - } - - private long getDeduplicationDuration(NotificationRuleTrigger trigger) { - if (triggerTypesConfigs == null) { - triggerTypesConfigs = new EnumMap<>(NotificationRuleTriggerType.class); - } - TriggerTypeConfig triggerTypeConfig = triggerTypesConfigs.computeIfAbsent(trigger.getType(), triggerType -> { - TriggerTypeConfig config = new TriggerTypeConfig(); - config.setDeduplicationDuration(trigger.getDefaultDeduplicationDuration()); - return config; - }); - return triggerTypeConfig.getDeduplicationDuration(); - } - - // set from ConfigurationProperties - public void setTriggerTypesConfigs(Map triggerTypesConfigs) { - if (triggerTypesConfigs != null) { - this.triggerTypesConfigs = new EnumMap<>(triggerTypesConfigs); - } - } - } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationRuleEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationRuleEntity.java index 15283c9fc1..e7a4b6a571 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationRuleEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationRuleEntity.java @@ -25,8 +25,8 @@ import org.thingsboard.server.common.data.id.NotificationTemplateId; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRuleRecipientsConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.util.mapping.JsonStringType; diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationRuleService.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationRuleService.java index 3cb92bd6ff..41cea42875 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationRuleService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationRuleService.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.id.NotificationRuleId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.entity.AbstractEntityService; diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java index 01f9f68ae4..4d4a1a63b8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java @@ -32,19 +32,19 @@ import org.thingsboard.server.common.data.notification.rule.DefaultNotificationR import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig.AlarmAction; -import org.thingsboard.server.common.data.notification.rule.trigger.ApiUsageLimitNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent; -import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmCommentNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig.AlarmAction; +import org.thingsboard.server.common.data.notification.rule.trigger.config.ApiUsageLimitNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EntitiesLimitNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig; import org.thingsboard.server.common.data.notification.template.WebDeliveryMethodNotificationTemplate; diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/NotificationRuleDao.java b/dao/src/main/java/org/thingsboard/server/dao/notification/NotificationRuleDao.java index 90eee4ba63..17d09c4404 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/NotificationRuleDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/NotificationRuleDao.java @@ -20,7 +20,7 @@ import org.thingsboard.server.common.data.id.NotificationTargetId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.Dao; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationRuleDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationRuleDao.java index aa3258287e..af9b8198e8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationRuleDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationRuleDao.java @@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.id.NotificationTargetId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.DaoUtil; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationRuleRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationRuleRepository.java index 1bdfe57bba..9dfb34c18d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationRuleRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationRuleRepository.java @@ -22,7 +22,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import org.thingsboard.server.dao.ExportableEntityRepository; import org.thingsboard.server.dao.model.sql.NotificationRuleEntity; import org.thingsboard.server.dao.model.sql.NotificationRuleInfoEntity; From 93e8770023a759a951d3f29f8b4e850c6474e3e4 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 8 Jun 2023 18:28:57 +0300 Subject: [PATCH 160/207] Don't write to cache on each deduplication --- .../DefaultNotificationDeduplicationService.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java b/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java index a233accf71..5284f1f1b4 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java @@ -69,8 +69,8 @@ public class DefaultNotificationDeduplicationService implements NotificationDedu } boolean alreadyProcessed = false; + long deduplicationDuration = getDeduplicationDuration(trigger); if (lastProcessedTs != null) { - long deduplicationDuration = getDeduplicationDuration(trigger); long passed = System.currentTimeMillis() - lastProcessedTs; log.trace("Deduplicating trigger {} by key '{}'. Deduplication duration: {} ms, passed: {} ms", trigger.getType(), deduplicationKey, deduplicationDuration, passed); @@ -84,9 +84,12 @@ public class DefaultNotificationDeduplicationService implements NotificationDedu } localCache.put(deduplicationKey, lastProcessedTs); if (!onlyLocalCache) { - Cache externalCache = cacheManager.getCache(CacheConstants.SENT_NOTIFICATIONS_CACHE); - if (externalCache != null) { - externalCache.put(deduplicationKey, lastProcessedTs); + if (!alreadyProcessed || deduplicationDuration == 0) { + // if lastProcessedTs is changed or if deduplicating infinitely (so that cache value not removed by ttl) + Cache externalCache = cacheManager.getCache(CacheConstants.SENT_NOTIFICATIONS_CACHE); + if (externalCache != null) { + externalCache.put(deduplicationKey, lastProcessedTs); + } } } return alreadyProcessed; From 44c784c248693deef2a3d6b0e1b0b900e8aea092 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 8 Jun 2023 18:37:06 +0300 Subject: [PATCH 161/207] refactoring --- .../mail/DefaultTbMailConfigTemplateService.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java index 2272a42b5b..cb502e7e51 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java @@ -21,14 +21,22 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; +import javax.annotation.PostConstruct; import java.io.IOException; @Service @Slf4j public class DefaultTbMailConfigTemplateService implements TbMailConfigTemplateService { + private JsonNode mailConfigTemplates; + + @PostConstruct + private void postConstruct() throws IOException { + mailConfigTemplates = JacksonUtil.toJsonNode(new ClassPathResource("/templates/mail_config_templates.json").getFile()); + } + @Override - public JsonNode findAllMailConfigTemplates() throws IOException { - return JacksonUtil.toJsonNode(new ClassPathResource("/templates/mail_config_templates.json").getFile()); + public JsonNode findAllMailConfigTemplates() { + return mailConfigTemplates; } } From 9d57be98bf3a603a3b741a6f89c711dd0249367c Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 9 Jun 2023 13:06:40 +0300 Subject: [PATCH 162/207] refactoring --- .../MailConfigTemplateController.java | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java index fc13edd3d7..09aed4fee3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java +++ b/application/src/main/java/org/thingsboard/server/controller/MailConfigTemplateController.java @@ -16,45 +16,21 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; -import com.nimbusds.jose.shaded.json.JSONObject; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.CharEncoding; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.ClassPathResource; -import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.data.ResourceType; -import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.mail.TbMailConfigTemplateService; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.core.io.ClassPathResource; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; -import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Base64; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; @@ -64,9 +40,7 @@ import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TE @RequestMapping("/api/mail/config/template") @Slf4j public class MailConfigTemplateController extends BaseController { - private static final String MAIL_CONFIG_TEMPLATE_ID = "mailConfigTemplateId"; private static final String MAIL_CONFIG_TEMPLATE_DEFINITION = "Mail configuration template is set of default smtp settings for mail server that specific provider supports"; - private final TbMailConfigTemplateService mailConfigTemplateService; @ApiOperation(value = "Get the list of all OAuth2 client registration templates (getClientRegistrationTemplates)" + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, From f191357b905f55fc7ec57adcdccff80470fa7aa5 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Fri, 9 Jun 2023 14:32:58 +0300 Subject: [PATCH 163/207] fixed NPE in Flow output node when it used after split array msg node --- .../thingsboard/server/common/msg/TbMsgProcessingCtx.java | 7 ++++++- .../rule/engine/transform/TbSplitArrayMsgNode.java | 6 ++++-- .../rule/engine/transform/TbSplitArrayMsgNodeTest.java | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java b/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java index 9010fc0b54..51cad0976f 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java @@ -64,7 +64,12 @@ public final class TbMsgProcessingCtx implements Serializable { } public TbMsgProcessingStackItem pop() { - return !stack.isEmpty() ? stack.removeLast() : null; + if (stack == null) { + throw new RuntimeException("Stack is null!"); + } else if (stack.isEmpty()) { + return null; + } + return stack.removeLast(); } public static TbMsgProcessingCtx fromProto(MsgProtos.TbMsgProcessingCtxProto ctx) { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNode.java index 7723d6028f..ae7ceade97 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNode.java @@ -77,8 +77,10 @@ public class TbSplitArrayMsgNode implements TbNode { ctx.tellFailure(msg, e); } }); - data.forEach(msgNode -> ctx.enqueueForTellNext(TbMsg.newMsg(msg.getQueueName(), msg.getType(), msg.getOriginator(), msg.getMetaData(), JacksonUtil.toString(msgNode)), - TbRelationTypes.SUCCESS, wrapper::onSuccess, wrapper::onFailure)); + data.forEach(msgNode -> { + TbMsg outMsg = TbMsg.transformMsg(msg, msg.getType(), msg.getOriginator(), msg.getMetaData(), JacksonUtil.toString(msgNode)); + ctx.enqueueForTellNext(outMsg, TbRelationTypes.SUCCESS, wrapper::onSuccess, wrapper::onFailure); + }); } } else { ctx.tellFailure(msg, new RuntimeException("Msg data is not a JSON Array!")); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java index 435ec91aaa..67ebf6f6fc 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbSplitArrayMsgNodeTest.java @@ -96,6 +96,7 @@ public class TbSplitArrayMsgNodeTest { ArgumentCaptor newMsgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor exceptionCaptor = ArgumentCaptor.forClass(Exception.class); verify(ctx, never()).tellSuccess(any()); + verify(ctx, never()).enqueueForTellNext(any(), anyString(), any(), any()); verify(ctx, times(1)).tellFailure(newMsgCaptor.capture(), exceptionCaptor.capture()); assertThat(exceptionCaptor.getValue()).isInstanceOf(RuntimeException.class); From a85d0b6129e21219b62deda25f524418fa739a22 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 9 Jun 2023 15:13:33 +0300 Subject: [PATCH 164/207] fix_bug_switch: add validation to tbel --- .../script/api/tbel/DefaultTbelInvokeService.java | 6 ++++++ ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js | 10 +++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java index f98e33b615..5497e6cbbc 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java @@ -25,6 +25,7 @@ import com.google.common.util.concurrent.MoreExecutors; import lombok.Getter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.mvel2.CompileException; import org.mvel2.ExecutionContext; import org.mvel2.MVEL; import org.mvel2.ParserContext; @@ -65,6 +66,8 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem protected final Map scriptIdToHash = new ConcurrentHashMap<>(); protected final Map scriptMap = new ConcurrentHashMap<>(); + private final String tbelSwitch = "switch"; + private final String tbelSwitchErrorMsg = "TBEL does not support the 'switch'."; protected Cache compiledScriptsCache; private SandboxedParserConfiguration parserConfig; @@ -181,6 +184,9 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem } return scriptId; } catch (Exception e) { + if (((CompileException) e).getExpr() != null && new String(((CompileException) e).getExpr()).contains(tbelSwitch)) { + e = new CompileException(tbelSwitchErrorMsg, ((CompileException) e).getExpr(), ((CompileException) e).getCursor(), e.getCause()); + } throw new TbScriptException(scriptId, TbScriptException.ErrorCode.COMPILATION, scriptBody, e); } }); diff --git a/ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js b/ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js index bc22e806c3..13ec1d821f 100644 --- a/ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js +++ b/ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js @@ -5229,6 +5229,10 @@ var JSHINT = (function() { var a = [], p; while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") { + if (state.tokens.next.value === "switch") { + warning("E067", state.tokens.next, "switch"); + break; + } if (state.tokens.next.id === ";") { p = peek(); @@ -9215,7 +9219,7 @@ var JSHINT = (function() { statements(0); } - if (state.tokens.next.id !== "(end)") { + if (state.tokens.next.id !== "(end)"&& state.tokens.next.value !== "switch") { quit("E041", state.tokens.curr); } @@ -11266,7 +11270,8 @@ var errors = { E064: "Super call may only be used within class method bodies.", E065: "Functions defined outside of strict mode with non-simple parameter lists may not " + "enable strict mode.", - E066: "Asynchronous iteration is only available with for-of loops." + E066: "Asynchronous iteration is only available with for-of loops.", + E067: "Expected without the 'switch' statement. TBEL does not support the 'switch' statement." }; var warnings = { @@ -11364,7 +11369,6 @@ var warnings = { W086: "Expected a 'break' statement before '{a}'.", W087: "Forgotten 'debugger' statement?", W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.", - // W288: "The syntax of function '{a}' is specific to TBEL, and is not supported by JS executor.", W089: "The body of a for in should be wrapped in an if statement to filter " + "unwanted properties from the prototype.", W090: "'{a}' is not a statement label.", From f534e2db6407ab949ffc013cd97abeb72cd75902 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 12 Jun 2023 13:05:10 +0300 Subject: [PATCH 165/207] fix_bug_switch: add validation to tbel mew msg --- ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js b/ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js index 13ec1d821f..3a4b3d90b8 100644 --- a/ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js +++ b/ui-ngx/src/app/shared/models/ace/tbel/worker-tbel.js @@ -11271,7 +11271,7 @@ var errors = { E065: "Functions defined outside of strict mode with non-simple parameter lists may not " + "enable strict mode.", E066: "Asynchronous iteration is only available with for-of loops.", - E067: "Expected without the 'switch' statement. TBEL does not support the 'switch' statement." + E067: "Expected an 'if/else' and instead saw 'switch'. TBEL does not support the 'switch' statement." }; var warnings = { From e5a2712d8947b4b5c60433f5e8728700ed682ebc Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Mon, 12 Jun 2023 13:53:10 +0300 Subject: [PATCH 166/207] changed logic to ack msg if stack is null --- .../thingsboard/server/common/msg/TbMsgProcessingCtx.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java b/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java index 51cad0976f..4e25ae17dc 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java @@ -64,12 +64,7 @@ public final class TbMsgProcessingCtx implements Serializable { } public TbMsgProcessingStackItem pop() { - if (stack == null) { - throw new RuntimeException("Stack is null!"); - } else if (stack.isEmpty()) { - return null; - } - return stack.removeLast(); + return stack == null || stack.isEmpty() ? null : stack.removeLast(); } public static TbMsgProcessingCtx fromProto(MsgProtos.TbMsgProcessingCtxProto ctx) { From 9ff84067037d269e2f116084dbfe124ca36dfec5 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Mon, 12 Jun 2023 14:17:55 +0300 Subject: [PATCH 167/207] added code style fixes && moved duplicate code block to method --- .../thingsboard/rule/engine/math/TbMathNode.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java index 26ec656443..33692decc2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java @@ -157,7 +157,7 @@ public class TbMathNode implements TbNode { private ListenableFuture updateMsgAndDb(TbContext ctx, TbMsg msg, Optional msgBodyOpt, double result) { TbMathResult mathResultDef = config.getResult(); - String mathResultKey = !mathResultDef.getType().equals(CONSTANT) ? TbNodeUtils.processPattern(mathResultDef.getKey(), msg) : mathResultDef.getKey(); + String mathResultKey = getKeyFromTemplate(msg, mathResultDef.getType(), mathResultDef.getKey()); switch (mathResultDef.getType()) { case MESSAGE_BODY: return Futures.immediateFuture(addToBody(msg, mathResultDef, mathResultKey, msgBodyOpt, result)); @@ -183,7 +183,7 @@ public class TbMathNode implements TbNode { private ListenableFuture saveAttribute(TbContext ctx, TbMsg msg, double result, TbMathResult mathResultDef) { String attributeScope = getAttributeScope(mathResultDef.getAttributeScope()); if (isIntegerResult(mathResultDef, config.getOperation())) { - var value = toIntValue(mathResultDef, result); + var value = toIntValue(result); return ctx.getTelemetryService().saveAttrAndNotify( ctx.getTenantId(), msg.getOriginator(), attributeScope, mathResultDef.getKey(), value); } else { @@ -197,7 +197,7 @@ public class TbMathNode implements TbNode { return function.isIntegerResult() || mathResultDef.getResultValuePrecision() == 0; } - private long toIntValue(TbMathResult mathResultDef, double value) { + private long toIntValue(double value) { return (long) value; } @@ -234,7 +234,7 @@ public class TbMathNode implements TbNode { private TbMsg addToBody(TbMsg msg, TbMathResult mathResultDef, String mathResultKey, Optional msgBodyOpt, double result) { ObjectNode body = msgBodyOpt.get(); if (isIntegerResult(mathResultDef, config.getOperation())) { - body.put(mathResultKey, toIntValue(mathResultDef, result)); + body.put(mathResultKey, toIntValue(result)); } else { body.put(mathResultKey, toDoubleValue(mathResultDef, result)); } @@ -244,7 +244,7 @@ public class TbMathNode implements TbNode { private TbMsg addToMeta(TbMsg msg, TbMathResult mathResultDef, String mathResultKey, double result) { var md = msg.getMetaData(); if (isIntegerResult(mathResultDef, config.getOperation())) { - md.putValue(mathResultKey, Long.toString(toIntValue(mathResultDef, result))); + md.putValue(mathResultKey, Long.toString(toIntValue(result))); } else { md.putValue(mathResultKey, Double.toString(toDoubleValue(mathResultDef, result))); } @@ -348,7 +348,7 @@ public class TbMathNode implements TbNode { } private ListenableFuture resolveArguments(TbContext ctx, TbMsg msg, Optional msgBodyOpt, TbMathArgument arg) { - String argKey = !arg.getType().equals(CONSTANT) ? TbNodeUtils.processPattern(arg.getKey(), msg) : arg.getKey(); + String argKey = getKeyFromTemplate(msg, arg.getType(), arg.getKey()); switch (arg.getType()) { case CONSTANT: return Futures.immediateFuture(TbMathArgumentValue.constant(arg)); @@ -371,6 +371,10 @@ public class TbMathNode implements TbNode { } + private String getKeyFromTemplate(TbMsg msg, TbMathArgumentType type, String keyPattern) { + return CONSTANT.equals(type) ? keyPattern : TbNodeUtils.processPattern(keyPattern, msg); + } + private String getAttributeScope(String attrScope) { return StringUtils.isEmpty(attrScope) ? DataConstants.SERVER_SCOPE : attrScope; } From a5de29c1f4731762332dd25284b47006cf76b224 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Mon, 12 Jun 2023 15:50:49 +0300 Subject: [PATCH 168/207] code readability fix --- .../thingsboard/server/common/msg/TbMsgProcessingCtx.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java b/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java index 4e25ae17dc..1b1cbcdf54 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/TbMsgProcessingCtx.java @@ -64,7 +64,10 @@ public final class TbMsgProcessingCtx implements Serializable { } public TbMsgProcessingStackItem pop() { - return stack == null || stack.isEmpty() ? null : stack.removeLast(); + if (stack == null || stack.isEmpty()) { + return null; + } + return stack.removeLast(); } public static TbMsgProcessingCtx fromProto(MsgProtos.TbMsgProcessingCtxProto ctx) { From 7f0c5f219b5bf7e91a09acd724c3659c736d9f42 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 12 Jun 2023 19:00:59 +0300 Subject: [PATCH 169/207] fix_bug_switch: add CompileException --- .../script/api/tbel/DefaultTbelInvokeService.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java index 5497e6cbbc..0e56612c21 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java @@ -183,11 +183,13 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem lock.unlock(); } return scriptId; - } catch (Exception e) { - if (((CompileException) e).getExpr() != null && new String(((CompileException) e).getExpr()).contains(tbelSwitch)) { - e = new CompileException(tbelSwitchErrorMsg, ((CompileException) e).getExpr(), ((CompileException) e).getCursor(), e.getCause()); + } catch (CompileException ce) { + if ( ce.getExpr() != null && new String(ce.getExpr()).contains(tbelSwitch)) { + ce = new CompileException(tbelSwitchErrorMsg, ce.getExpr(), ce.getCursor(), ce.getCause()); } - throw new TbScriptException(scriptId, TbScriptException.ErrorCode.COMPILATION, scriptBody, e); + throw new TbScriptException(scriptId, TbScriptException.ErrorCode.COMPILATION, scriptBody, ce); + } catch (Exception e) { + throw new RuntimeException(e); } }); } From fff879a6cf3c9aae3d1d985012cfd323d651a187 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Mon, 12 Jun 2023 19:24:30 +0300 Subject: [PATCH 170/207] UI: Fixed oauth2 form array trackby --- .../home/pages/admin/oauth2-settings.component.html | 8 ++++---- .../modules/home/pages/admin/oauth2-settings.component.ts | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.html b/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.html index bc5ffd3ae5..7cc06bc4af 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.html +++ b/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.html @@ -37,7 +37,7 @@
- + @@ -59,7 +59,7 @@
-
@@ -146,7 +146,7 @@ admin.oauth2.no-mobile-apps
-
@@ -203,7 +203,7 @@
admin.oauth2.providers
- diff --git a/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts b/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts index 34f35611b4..d274f6728e 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts @@ -570,4 +570,8 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha trackByParams(index: number): number { return index; } + + trackByItem(i, item) { + return item; + } } From 6d69c9b2138cdad0b767d63c6cce858957368e22 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 13 Jun 2023 11:39:48 +0300 Subject: [PATCH 171/207] fix_bug_switch: add CompileException2 --- .../thingsboard/script/api/tbel/DefaultTbelInvokeService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java index 0e56612c21..bbf441a659 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java @@ -189,7 +189,7 @@ public class DefaultTbelInvokeService extends AbstractScriptInvokeService implem } throw new TbScriptException(scriptId, TbScriptException.ErrorCode.COMPILATION, scriptBody, ce); } catch (Exception e) { - throw new RuntimeException(e); + throw new TbScriptException(scriptId, TbScriptException.ErrorCode.COMPILATION, scriptBody, e); } }); } From 7ac6eac802059a303880eb9ed468b927985505f7 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Tue, 13 Jun 2023 12:13:51 +0300 Subject: [PATCH 172/207] UI: Fixed oauth2 mail server settings --- .../app/modules/home/pages/admin/mail-server.component.html | 2 +- .../src/app/modules/home/pages/admin/mail-server.component.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.html b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.html index 2762e0d43a..926ad64644 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.html +++ b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.html @@ -331,7 +331,7 @@
diff --git a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.ts b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.ts index 6815c81e31..d95c3d6096 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/mail-server.component.ts @@ -416,6 +416,9 @@ export class MailServerComponent extends PageComponent implements OnInit, OnDest private get mailSettingsFormValue(): MailServerSettings { const formValue = this.mailSettings.getRawValue() as Required; delete formValue.changePassword; + if (!isDefinedAndNotNull(formValue.password)) { + delete formValue.password; + } return formValue; } From 0bd7f74c47e3b17a14a30189749d56c74a7771cb Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 13 Jun 2023 14:12:54 +0300 Subject: [PATCH 173/207] Fix issues --- .../rule/trigger/RateLimitsTriggerProcessor.java | 6 +++--- application/src/main/resources/thingsboard.yml | 2 +- .../notification/NotificationRuleApiTest.java | 12 ++++++------ .../rule}/trigger/RateLimitsTrigger.java | 4 ++-- .../RateLimitsNotificationRuleTriggerConfig.java | 2 +- .../DefaultNotificationDeduplicationService.java | 14 +++++++++++--- .../transport/service/DefaultTransportService.java | 2 +- .../dao/notification/DefaultNotifications.java | 2 +- .../dao/util/limits/DefaultRateLimitService.java | 2 +- .../src/main/resources/tb-vc-executor.yml | 6 ++---- .../coap/src/main/resources/tb-coap-transport.yml | 6 ++---- .../http/src/main/resources/tb-http-transport.yml | 6 ++---- .../src/main/resources/tb-lwm2m-transport.yml | 6 ++---- .../mqtt/src/main/resources/tb-mqtt-transport.yml | 6 ++---- .../snmp/src/main/resources/tb-snmp-transport.yml | 6 ++---- 15 files changed, 39 insertions(+), 43 deletions(-) rename common/{message/src/main/java/org/thingsboard/server/common/msg/notification => data/src/main/java/org/thingsboard/server/common/data/notification/rule}/trigger/RateLimitsTrigger.java (94%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{ => config}/RateLimitsNotificationRuleTriggerConfig.java (99%) diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java index 910ef4866f..bec1502427 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/RateLimitsTriggerProcessor.java @@ -21,10 +21,10 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.info.RateLimitsNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.RateLimitsNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.util.CollectionsUtil; -import org.thingsboard.server.common.msg.notification.trigger.RateLimitsTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.tenant.TenantService; diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 962b1f4cff..e7fbbd2a3d 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -1277,7 +1277,7 @@ notification_system: thread_pool_size: "${TB_NOTIFICATION_SYSTEM_THREAD_POOL_SIZE:10}" rules: # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' - deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:NEW_PLATFORM_VERSION:0;}" + deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:NEW_PLATFORM_VERSION:0;RATE_LIMITS:14400000;}" management: endpoints: diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java index 7f66dd78df..f89730b689 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java @@ -64,6 +64,8 @@ import org.thingsboard.server.common.data.notification.rule.DefaultNotificationR import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo; +import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger; import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmAssignmentNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmCommentNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig; @@ -73,7 +75,7 @@ import org.thingsboard.server.common.data.notification.rule.trigger.config.Entit import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.RateLimitsNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.platform.AffectedTenantAdministratorsFilter; import org.thingsboard.server.common.data.notification.targets.platform.SystemAdministratorsFilter; @@ -87,14 +89,12 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionTrigger; -import org.thingsboard.server.common.msg.notification.trigger.RateLimitsTrigger; import org.thingsboard.server.dao.notification.DefaultNotifications; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.util.limits.RateLimitService; -import org.thingsboard.server.service.notification.rule.DefaultNotificationRuleProcessor; +import org.thingsboard.server.queue.notification.DefaultNotificationDeduplicationService; import org.thingsboard.server.service.notification.rule.cache.DefaultNotificationRulesCache; import org.thingsboard.server.service.state.DeviceStateService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; @@ -125,7 +125,7 @@ import static org.thingsboard.server.common.data.notification.rule.trigger.confi @DaoSqlTest @TestPropertySource(properties = { "transport.http.enabled=true", - "notification_system.rules.trigger_types_configs.RATE_LIMITS.deduplication_duration=10000" + "notification_system.rules.deduplication_durations=RATE_LIMITS:10000" }) public class NotificationRuleApiTest extends AbstractNotificationApiTest { @@ -700,7 +700,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest { .api(LimitedApi.ENTITY_EXPORT) .limitLevel(tenantId) .build(); - assertThat(DefaultNotificationRuleProcessor.getDeduplicationKey(expectedTrigger, rule)) + assertThat(DefaultNotificationDeduplicationService.getDeduplicationKey(expectedTrigger, rule)) .isEqualTo("RATE_LIMITS:TENANT:" + tenantId + ":ENTITY_EXPORT_" + target.getId() + ":ENTITY_EXPORT,TRANSPORT_MESSAGES_PER_DEVICE"); diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RateLimitsTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsTrigger.java similarity index 94% rename from common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RateLimitsTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsTrigger.java index afb06bb8d1..3941ade824 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/notification/trigger/RateLimitsTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsTrigger.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.msg.notification.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.limit.LimitedApi; -import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; +import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; import java.util.concurrent.TimeUnit; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/RateLimitsNotificationRuleTriggerConfig.java similarity index 99% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/RateLimitsNotificationRuleTriggerConfig.java index f5ea83c47d..6cb447bc8f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/RateLimitsNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/RateLimitsNotificationRuleTriggerConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.data.notification.rule.trigger; +package org.thingsboard.server.common.data.notification.rule.trigger.config; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java b/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java index 5284f1f1b4..871408ac40 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/notification/DefaultNotificationDeduplicationService.java @@ -31,6 +31,7 @@ import org.thingsboard.server.queue.util.PropertyUtils; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ConcurrentMap; import static org.springframework.util.ConcurrentReferenceHashMap.ReferenceType.SOFT; @@ -42,7 +43,8 @@ public class DefaultNotificationDeduplicationService implements NotificationDedu private Map deduplicationDurations; - private final CacheManager cacheManager; + @Autowired(required = false) + private CacheManager cacheManager; private final ConcurrentMap localCache = new ConcurrentReferenceHashMap<>(16, SOFT); @Override @@ -60,7 +62,7 @@ public class DefaultNotificationDeduplicationService implements NotificationDedu private boolean alreadyProcessed(NotificationRuleTrigger trigger, String deduplicationKey, boolean onlyLocalCache) { Long lastProcessedTs = localCache.get(deduplicationKey); if (lastProcessedTs == null && !onlyLocalCache) { - Cache externalCache = cacheManager.getCache(CacheConstants.SENT_NOTIFICATIONS_CACHE); + Cache externalCache = getExternalCache(); if (externalCache != null) { lastProcessedTs = externalCache.get(deduplicationKey, Long.class); } else { @@ -86,7 +88,7 @@ public class DefaultNotificationDeduplicationService implements NotificationDedu if (!onlyLocalCache) { if (!alreadyProcessed || deduplicationDuration == 0) { // if lastProcessedTs is changed or if deduplicating infinitely (so that cache value not removed by ttl) - Cache externalCache = cacheManager.getCache(CacheConstants.SENT_NOTIFICATIONS_CACHE); + Cache externalCache = getExternalCache(); if (externalCache != null) { externalCache.put(deduplicationKey, lastProcessedTs); } @@ -105,6 +107,12 @@ public class DefaultNotificationDeduplicationService implements NotificationDedu }); } + private Cache getExternalCache() { + return Optional.ofNullable(cacheManager) + .map(cacheManager -> cacheManager.getCache(CacheConstants.SENT_NOTIFICATIONS_CACHE)) + .orElse(null); + } + @Autowired public void setDeduplicationDurations(@Value("${notification_system.rules.deduplication_durations:}") String deduplicationDurationsStr) { diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 69e4de7b74..3b827edbae 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -53,7 +53,7 @@ import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.msg.notification.trigger.RateLimitsTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.session.SessionMsgType; diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java index abe20e245d..a6c558a388 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java @@ -45,7 +45,7 @@ import org.thingsboard.server.common.data.notification.rule.trigger.config.Entit import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.RateLimitsNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig; diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java b/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java index ede6855d5e..12201712c1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java @@ -29,7 +29,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.common.msg.notification.trigger.RateLimitsTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger; import org.thingsboard.server.common.msg.tools.TbRateLimits; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; diff --git a/msa/vc-executor/src/main/resources/tb-vc-executor.yml b/msa/vc-executor/src/main/resources/tb-vc-executor.yml index 75f9e09d3c..094e0e2099 100644 --- a/msa/vc-executor/src/main/resources/tb-vc-executor.yml +++ b/msa/vc-executor/src/main/resources/tb-vc-executor.yml @@ -206,7 +206,5 @@ service: notification_system: rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" + # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' + deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:RATE_LIMITS:14400000;}" diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml index 0a7635ff40..b9db930657 100644 --- a/transport/coap/src/main/resources/tb-coap-transport.yml +++ b/transport/coap/src/main/resources/tb-coap-transport.yml @@ -315,7 +315,5 @@ management: notification_system: rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" + # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' + deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:RATE_LIMITS:14400000;}" diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml index fa2e033d0c..bff7adb561 100644 --- a/transport/http/src/main/resources/tb-http-transport.yml +++ b/transport/http/src/main/resources/tb-http-transport.yml @@ -300,7 +300,5 @@ management: notification_system: rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" + # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' + deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:RATE_LIMITS:14400000;}" diff --git a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml index 6b90d60b3d..ae8f0138a7 100644 --- a/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml +++ b/transport/lwm2m/src/main/resources/tb-lwm2m-transport.yml @@ -382,7 +382,5 @@ management: notification_system: rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" + # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' + deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:RATE_LIMITS:14400000;}" diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml index 031d01e987..076dde0234 100644 --- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml +++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml @@ -330,7 +330,5 @@ management: notification_system: rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" + # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' + deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:RATE_LIMITS:14400000;}" diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index b6bffd8d4b..c68c9c56a8 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -280,7 +280,5 @@ management: notification_system: rules: - trigger_types_configs: - RATE_LIMITS: - # In milliseconds, 4 hours by default - deduplication_duration: "${RATE_LIMITS_NOTIFICATION_RULE_DEDUPLICATION_DURATION:14400000}" + # Semicolon-separated deduplication durations (in millis) for trigger types. Format: 'NotificationRuleTriggerType1:123;NotificationRuleTriggerType2:456' + deduplication_durations: "${TB_NOTIFICATION_RULES_DEDUPLICATION_DURATIONS:RATE_LIMITS:14400000;}" From 50d3a6d92500ed63ee7f59585c617866e6c1329e Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Wed, 14 Jun 2023 13:10:52 +0300 Subject: [PATCH 174/207] tbel: add parseBytesToFloat --- .../thingsboard/script/api/tbel/TbUtils.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index 6c50561363..10d48d582a 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -15,6 +15,7 @@ */ package org.thingsboard.script.api.tbel; +import com.google.common.primitives.Bytes; import org.mvel2.ExecutionContext; import org.mvel2.ParserConfiguration; import org.mvel2.execution.ExecutionArrayList; @@ -81,6 +82,14 @@ public class TbUtils { byte[].class, int.class, int.class))); parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt", byte[].class, int.class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", + byte[].class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", + byte[].class, int.class))); + parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", + List.class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", + List.class, int.class))); parserConfig.addImport("toFixed", new MethodStub(TbUtils.class.getMethod("toFixed", double.class, int.class))); parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes", @@ -293,6 +302,33 @@ public class TbUtils { return bb.getInt(); } + public static float parseBytesToFloat(byte[] data, int offset) { + return parseBytesToFloat(data, offset, true); + } + + public static float parseBytesToFloat(byte[] data, int offset, boolean bigEndian) { + if (data != null && data.length > 0) { + int length = 4; + if (offset > data.length) { + throw new IllegalArgumentException("Offset: " + offset + " is out of bounds for array with length: " + data.length + "!"); + } + if ((offset + length) > data.length) { + throw new IllegalArgumentException("Default length is always 4 bytes. Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!"); + } + int i = parseBytesToInt(data, offset, length, bigEndian); + return Float.intBitsToFloat(i); + } else { + throw new IllegalArgumentException("Array is null or array length is 0!"); + } + } + public static float parseBytesToFloat(List data, int offset) { + return parseBytesToFloat(data, offset, true); + } + + public static float parseBytesToFloat(List data, int offset, boolean bigEndian) { + return parseBytesToFloat(Bytes.toArray(data), offset, bigEndian); + } + public static String bytesToHex(ExecutionArrayList bytesList) { byte[] bytes = new byte[bytesList.size()]; for (int i = 0; i < bytesList.size(); i++) { From d7c3f1647a71bd8a466ada3eb9d1d9e996edf24e Mon Sep 17 00:00:00 2001 From: kalytka Date: Wed, 14 Jun 2023 14:57:16 +0300 Subject: [PATCH 175/207] Updated enrichment rule nodes UI --- .../resources/public/static/rulenode/rulenode-core-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js index 414c734227..b143649869 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js +++ b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js @@ -1 +1 @@ -System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/platform-browser","@angular/material/select","@angular/material/core","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/icon","@angular/material/chips","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/material/tooltip","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","rxjs","@angular/material/expansion","@home/components/public-api","tslib","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@angular/material/slide-toggle","@home/components/relation/relation-filters.component","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@angular/material/button-toggle","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,u,p,d,c,f,g,y,x,b,h,C,v,F,L,k,T,I,N,S,q,M,A,G,E,D,V,w,P,R,O,H,K,B,U,z,_,j,$,Q,J,Y,W,X,Z,ee,te,ne,re,oe,ae,ie,le,se,me,ue,pe,de,ce,fe,ge,ye,xe,be,he,Ce,ve,Fe,Le,ke,Te,Ie,Ne,Se,qe,Me,Ae,Ge,Ee,De,Ve,we,Pe,Re,Oe,He,Ke,Be,Ue,ze,_e,je;return{setters:[function(e){t=e,n=e.Component,r=e.Pipe,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.NgModule},function(e){s=e.RuleNodeConfigurationComponent,m=e.AttributeScope,u=e.telemetryTypeTranslations,p=e.ServiceType,d=e.ScriptLanguage,c=e.AlarmSeverity,f=e.alarmSeverityTranslations,g=e.EntitySearchDirection,y=e.entitySearchDirectionTranslations,x=e.EntityType,b=e.PageComponent,h=e.coerceBoolean,C=e.MessageType,v=e.messageTypeNames,F=e,L=e.SharedModule,k=e.AggregationType,T=e.aggregationTranslations,I=e.NotificationType,N=e.SlackChanelType,S=e.SlackChanelTypesTranslateMap,q=e.alarmStatusTranslations,M=e.AlarmStatus},function(e){A=e},function(e){G=e,E=e.Validators,D=e.NgControl,V=e.NG_VALUE_ACCESSOR,w=e.NG_VALIDATORS,P=e.FormControl,R=e.UntypedFormControl},function(e){O=e,H=e.CommonModule},function(e){K=e},function(e){B=e},function(e){U=e},function(e){z=e},function(e){_=e},function(e){j=e},function(e){$=e},function(e){Q=e},function(e){J=e},function(e){Y=e.getCurrentAuthState,W=e,X=e.isDefinedAndNotNull,Z=e.isObject,ee=e.isNotEmptyStr},function(e){te=e},function(e){ne=e},function(e){re=e},function(e){oe=e.ENTER,ae=e.COMMA,ie=e.SEMICOLON},function(e){le=e},function(e){se=e},function(e){me=e},function(e){ue=e},function(e){pe=e.coerceBooleanProperty},function(e){de=e},function(e){ce=e},function(e){fe=e},function(e){ge=e},function(e){ye=e},function(e){xe=e.tap,be=e.map,he=e.mergeMap,Ce=e.takeUntil,ve=e.startWith,Fe=e.share,Le=e.distinctUntilChanged},function(e){ke=e},function(e){Te=e},function(e){Ie=e.of,Ne=e.Subject},function(e){Se=e},function(e){qe=e.HomeComponentsModule},function(e){Me=e.__decorate},function(e){Ae=e},function(e){Ge=e},function(e){Ee=e},function(e){De=e},function(e){Ve=e},function(e){we=e},function(e){Pe=e},function(e){Re=e},function(e){Oe=e},function(e){He=e},function(e){Ke=e},function(e){Be=e},function(e){Ue=e},function(e){ze=e},function(e){_e=e},function(e){je=e}],execute:function(){class $e extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",$e),$e.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$e.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$e,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$e,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qe{constructor(e){this.sanitizer=e}transform(e){return this.sanitizer.bypassSecurityTrustHtml(e)}}e("SafeHtmlPipe",Qe),Qe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,deps:[{token:j.DomSanitizer}],target:t.ɵɵFactoryTarget.Pipe}),Qe.ɵpipe=t.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Qe,name:"safeHtml"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qe,decorators:[{type:r,args:[{name:"safeHtml"}]}],ctorParameters:function(){return[{type:j.DomSanitizer}]}});class Je extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[E.required,E.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[E.required,E.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",Je),Je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Je.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Je,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Je,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Ye extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===m.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",Ye),Ye.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ye.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ye,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ye,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class We extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[E.required]]})}}e("CheckPointConfigComponent",We),We.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),We.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:We,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:We,decorators:[{type:n,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Xe extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[E.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===d.JS?[E.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===d.TBEL?[E.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.clearAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",r=this.clearAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.clearAlarmConfigForm.get(t).setValue(e)}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",Xe),Xe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xe,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xe,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Ze extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.alarmSeverities=Object.keys(c),this.alarmSeverityTranslationMap=f,this.separatorKeysCodes=[oe,ae,ie],this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([E.required]),this.createAlarmConfigForm.get("severity").setValidators([E.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==d.TBEL||this.tbelEnabled||(r=d.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===d.JS?[E.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===d.TBEL?[E.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.createAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",r=this.createAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.createAlarmConfigForm.get(t).setValue(e)}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",Ze),Ze.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ze,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ze.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ze,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ze,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class et extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[E.required]],entityType:[e?e.entityType:null,[E.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[E.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[E.required,E.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==x.DEVICE&&t!==x.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([E.required,E.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",et),et.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:et,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),et.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:et,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:et,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class tt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[E.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[E.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[E.required,E.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([E.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",tt),tt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,E.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,E.required]})}}e("DeviceProfileConfigComponent",nt),nt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class rt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[E.required,E.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[E.required,E.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(){const e=this.generatorConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",r=this.generatorConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.generatorConfigForm.get(t).setValue(e)}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}var ot;e("GeneratorConfigComponent",rt),rt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rt,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),rt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rt,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rt,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(ot||(ot={}));const at=new Map([[ot.CUSTOMER,"tb.rulenode.originator-customer"],[ot.TENANT,"tb.rulenode.originator-tenant"],[ot.RELATED,"tb.rulenode.originator-related"],[ot.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[ot.ENTITY,"tb.rulenode.originator-entity"]]);var it;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(it||(it={}));const lt=new Map([[it.CIRCLE,"tb.rulenode.perimeter-circle"],[it.POLYGON,"tb.rulenode.perimeter-polygon"]]);var st;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(st||(st={}));const mt=new Map([[st.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[st.SECONDS,"tb.rulenode.time-unit-seconds"],[st.MINUTES,"tb.rulenode.time-unit-minutes"],[st.HOURS,"tb.rulenode.time-unit-hours"],[st.DAYS,"tb.rulenode.time-unit-days"]]);var ut;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(ut||(ut={}));const pt=new Map([[ut.METER,"tb.rulenode.range-unit-meter"],[ut.KILOMETER,"tb.rulenode.range-unit-kilometer"],[ut.FOOT,"tb.rulenode.range-unit-foot"],[ut.MILE,"tb.rulenode.range-unit-mile"],[ut.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var dt,ct;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(dt||(dt={})),function(e){e.NAME="name",e.CREATED_TIME="createdTime",e.TYPE="type",e.FIRST_NAME="firstName",e.LAST_NAME="lastName",e.EMAIL="email",e.TITLE="title",e.COUNTRY="county",e.STATE="state",e.CITY="city",e.ADDRESS="address",e.ADDRESS2="address2",e.ZIP="zip",e.PHONE="phone",e.LABEL="label"}(ct||(ct={}));const ft=new Map([[ct.NAME,"tb.rulenode.name"],[ct.CREATED_TIME,"tb.rulenode.created-time"],[ct.TYPE,"tb.rulenode.type"],[ct.FIRST_NAME,"tb.rulenode.first-name"],[ct.LAST_NAME,"tb.rulenode.last-name"],[ct.EMAIL,"tb.rulenode.entity-details-email"],[ct.TITLE,"tb.rulenode.entity-details-title"],[ct.COUNTRY,"tb.rulenode.entity-details-country"],[ct.STATE,"tb.rulenode.entity-details-state"],[ct.CITY,"tb.rulenode.entity-details-city"],[ct.ADDRESS,"tb.rulenode.entity-details-address"],[ct.ADDRESS2,"tb.rulenode.entity-details-address2"],[ct.ZIP,"tb.rulenode.entity-details-zip"],[ct.PHONE,"tb.rulenode.entity-details-phone"],[ct.LABEL,"tb.rulenode.label"]]),gt=new Map([[dt.ID,"tb.rulenode.entity-details-id"],[dt.TITLE,"tb.rulenode.entity-details-title"],[dt.COUNTRY,"tb.rulenode.entity-details-country"],[dt.STATE,"tb.rulenode.entity-details-state"],[dt.CITY,"tb.rulenode.entity-details-city"],[dt.ZIP,"tb.rulenode.entity-details-zip"],[dt.ADDRESS,"tb.rulenode.entity-details-address"],[dt.ADDRESS2,"tb.rulenode.entity-details-address2"],[dt.PHONE,"tb.rulenode.entity-details-phone"],[dt.EMAIL,"tb.rulenode.entity-details-email"],[dt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var yt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(yt||(yt={}));const xt=new Map([[yt.FIRST,"tb.rulenode.first"],[yt.LAST,"tb.rulenode.last"],[yt.ALL,"tb.rulenode.all"]]);var bt,ht;!function(e){e.ASC="ASC",e.DESC="DESC"}(bt||(bt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(ht||(ht={}));const Ct=new Map([[bt.ASC,"tb.rulenode.ascending"],[bt.DESC,"tb.rulenode.descending"]]);var vt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(vt||(vt={}));const Ft=new Map([[vt.STANDARD,"tb.rulenode.sqs-queue-standard"],[vt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),Lt=["anonymous","basic","cert.PEM"],kt=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Tt=["sas","cert.PEM"],It=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var Nt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(Nt||(Nt={}));const St=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],qt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Mt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Mt||(Mt={}));const At=new Map([[Mt.CUSTOM,{value:Mt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Mt.ADD,{value:Mt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Mt.SUB,{value:Mt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Mt.MULT,{value:Mt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Mt.DIV,{value:Mt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Mt.SIN,{value:Mt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Mt.SINH,{value:Mt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Mt.COS,{value:Mt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Mt.COSH,{value:Mt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Mt.TAN,{value:Mt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Mt.TANH,{value:Mt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Mt.ACOS,{value:Mt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Mt.ASIN,{value:Mt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Mt.ATAN,{value:Mt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Mt.ATAN2,{value:Mt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Mt.EXP,{value:Mt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Mt.EXPM1,{value:Mt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Mt.SQRT,{value:Mt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Mt.CBRT,{value:Mt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Mt.GET_EXP,{value:Mt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Mt.HYPOT,{value:Mt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Mt.LOG,{value:Mt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Mt.LOG10,{value:Mt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Mt.LOG1P,{value:Mt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Mt.CEIL,{value:Mt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Mt.FLOOR,{value:Mt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Mt.FLOOR_DIV,{value:Mt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Mt.FLOOR_MOD,{value:Mt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Mt.ABS,{value:Mt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Mt.MIN,{value:Mt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Mt.MAX,{value:Mt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Mt.POW,{value:Mt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Mt.SIGNUM,{value:Mt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Mt.RAD,{value:Mt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Mt.DEG,{value:Mt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Gt,Et,Dt;!function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Gt||(Gt={})),function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Et||(Et={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(Dt||(Dt={}));const Vt=new Map([[Gt.ATTRIBUTE,"tb.rulenode.attribute-type"],[Gt.TIME_SERIES,"tb.rulenode.time-series-type"],[Gt.CONSTANT,"tb.rulenode.constant-type"],[Gt.MESSAGE_BODY,"tb.rulenode.message-body-type"],[Gt.MESSAGE_METADATA,"tb.rulenode.message-metadata-type"]]),wt=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var Pt,Rt;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(Pt||(Pt={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(Rt||(Rt={}));const Ot=new Map([[Pt.SHARED_SCOPE,"tb.rulenode.shared-scope"],[Pt.SERVER_SCOPE,"tb.rulenode.server-scope"],[Pt.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class Ht extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=it,this.perimeterTypes=Object.keys(it),this.perimeterTypeTranslationMap=lt,this.rangeUnits=Object.keys(ut),this.rangeUnitTranslationMap=pt,this.timeUnits=Object.keys(st),this.timeUnitsTranslationMap=mt}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[E.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[E.required]],perimeterType:[e?e.perimeterType:null,[E.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[E.required,E.min(1),E.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[E.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[E.required,E.min(1),E.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[E.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([E.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==it.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([E.required,E.min(-90),E.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([E.required,E.min(-180),E.max(180)]),this.geoActionConfigForm.get("range").setValidators([E.required,E.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([E.required])),t||n!==it.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([E.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",Ht),Ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ht,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ht,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Kt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.logConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",r=this.logConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.logConfigForm.get(t).setValue(e)}))}onValidate(){this.logConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",Kt),Kt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Kt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kt,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kt,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Bt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[E.required,E.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[E.required]]})}}e("MsgCountConfigComponent",Bt),Bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Bt,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bt,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Ut extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[E.required,E.min(1),E.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([E.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([E.required,E.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",Ut),Ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ut,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ut,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class zt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]]})}}e("PushToCloudConfigComponent",zt),zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zt,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zt,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class _t extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]]})}}e("PushToEdgeConfigComponent",_t),_t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_t,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_t,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",jt),jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jt,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jt,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class $t extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[E.required,E.min(0)]]})}}e("RpcRequestConfigComponent",$t),$t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$t,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$t,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required]],value:[e[n],[E.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[E.required]],value:["",[E.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Qt),Qt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qt,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:V,useExisting:a((()=>Qt)),multi:!0},{provide:w,useExisting:a((()=>Qt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qt,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:V,useExisting:a((()=>Qt)),multi:!0},{provide:w,useExisting:a((()=>Qt)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class Jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[E.required,E.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[E.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",Jt),Jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jt,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jt,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Yt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[E.required,E.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Yt),Yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yt,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yt,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Wt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[E.required,E.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[E.required,E.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Wt),Wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Wt,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wt,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Xt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[E.required]],keys:[e?e.keys:null,[E.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",Xt),Xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xt,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Zt extends b{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup())}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=At,this.ArgumentType=Gt,this.attributeScopeMap=Ot,this.argumentTypeResultMap=Vt,this.arguments=Object.values(Gt),this.attributeScope=Object.values(Pt),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.argumentsFormGroup=this.fb.group({}),this.argumentsFormGroup.addControl("arguments",this.fb.array([])),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray(),n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):this.argumentsFormGroup.enable({emitEvent:!1})}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()));const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t)),this.setupArgumentsFormGroup(),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()})))}removeArgument(e){this.argumentsFormGroup.get("arguments").removeAt(e),this.updateArgumentNames()}addArgument(){const e=this.argumentsFormGroup.get("arguments"),t=this.createArgumentControl(null,e.length);e.push(t)}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Mt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([E.minLength(this.minArgs),E.maxLength(this.maxArgs)]),this.argumentsFormGroup.get("arguments").value.length>this.maxArgs&&(this.argumentsFormGroup.get("arguments").controls.length=this.maxArgs);this.argumentsFormGroup.get("arguments").value.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!0}),n.get("defaultValue").updateValueAndValidity({emitEvent:!0})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Gt.ATTRIBUTE?e.get("attributeScope").enable():e.get("attributeScope").disable(),t&&t!==Gt.CONSTANT?e.get("defaultValue").enable():e.get("defaultValue").disable()}updateArgumentNames(){this.argumentsFormGroup.get("arguments").controls.forEach(((e,t)=>{e.get("name").setValue(wt[t])}))}updateModel(){const e=this.argumentsFormGroup.get("arguments").value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Zt),Zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Zt,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:V,useExisting:a((()=>Zt)),multi:!0},{provide:w,useExisting:a((()=>Zt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"],dependencies:[{kind:"directive",type:O.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ge.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:ge.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:ye.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:ye.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:ye.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zt,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:V,useExisting:a((()=>Zt)),multi:!0},{provide:w,useExisting:a((()=>Zt)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n
\n \n
\n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:10px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class en extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...At.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(xe((e=>{let t;t="string"==typeof e&&Mt[e]?Mt[e]:null,this.updateView(t)})),be((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=At.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",en),en.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:en,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),en.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:en,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:V,useExisting:a((()=>en)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:en,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:V,useExisting:a((()=>en)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Mt,this.ArgumentTypeResult=Et,this.argumentTypeResultMap=Vt,this.attributeScopeMap=Ot,this.argumentsResult=Object.values(Et),this.attributeScopeResult=Object.values(Rt)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[E.required]],arguments:[e?e.arguments:null,[E.required]],customFunction:[e?e.customFunction:"",[E.required]],result:this.fb.group({type:[e?e.result.type:null,[E.required]],attributeScope:[e?e.result.attributeScope:null],key:[e?e.result.key:"",[E.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result").get("type").value;t===Mt.CUSTOM?this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Et.ATTRIBUTE?this.mathFunctionConfigForm.get("result").get("attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result").get("attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result").get("attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",tn),tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tn,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Zt,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:en,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tn,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block;margin-top:16px}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nn{constructor(e,t){this.store=e,this.fb=t,this.subscriptSizing="fixed",this.searchText="",this.dirty=!1,this.messageTypes=["POST_ATTRIBUTES_REQUEST","POST_TELEMETRY_REQUEST"],this.propagateChange=e=>{},this.messageTypeFormGroup=this.fb.group({messageType:[null,[E.required,E.maxLength(255)]]})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.outputMessageTypes=this.messageTypeFormGroup.get("messageType").valueChanges.pipe(xe((e=>{this.updateView(e)})),be((e=>e||"")),he((e=>this.fetchMessageTypes(e))))}writeValue(e){this.searchText="",this.modelValue=e,this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1}),this.dirty=!0}onFocus(){this.dirty&&(this.messageTypeFormGroup.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0}),this.dirty=!1)}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}displayMessageTypeFn(e){return e||void 0}fetchMessageTypes(e,t=!1){return this.searchText=e,Ie(this.messageTypes).pipe(be((n=>n.filter((n=>t?!!e&&n===e:!e||n.toUpperCase().startsWith(e.toUpperCase()))))))}clear(){this.messageTypeFormGroup.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}}e("OutputMessageTypeAutocompleteComponent",nn),nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nn,selector:"tb-output-message-type-autocomplete",inputs:{autocompleteHint:"autocompleteHint",subscriptSizing:"subscriptSizing"},providers:[{provide:V,useExisting:a((()=>nn)),multi:!0}],viewQueries:[{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0,static:!0}],ngImport:t,template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:V,useExisting:a((()=>nn)),multi:!0}],template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{messageTypeInput:[{type:o,args:["messageTypeInput",{static:!0}]}],autocompleteHint:[{type:i}],subscriptSizing:[{type:i}]}});class rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.destroy$=new Ne,this.serviceType=p.TB_RULE_ENGINE,this.deduplicationStrategie=yt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=xt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[X(e?.interval)?e.interval:null,[E.required,E.min(1)]],strategy:[X(e?.strategy)?e.strategy:null,[E.required]],outMsgType:[X(e?.outMsgType)?e.outMsgType:null,[E.required]],queueName:[X(e?.queueName)?e.queueName:null,[E.required]],maxPendingMsgs:[X(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[E.required,E.min(1),E.max(1e3)]],maxRetries:[X(e?.maxRetries)?e.maxRetries:null,[E.required,E.min(0),E.max(100)]]}),this.deduplicationConfigForm.get("strategy").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.enableControl(e)}))}updateValidators(e){this.enableControl(this.deduplicationConfigForm.get("strategy").value)}validatorTriggers(){return["strategy"]}enableControl(e){e===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("DeduplicationConfigComponent",rn),rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rn,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:nn,selector:"tb-output-message-type-autocomplete",inputs:["autocompleteHint","subscriptSizing"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class on extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[e[n],[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",on),on.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:on,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),on.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:on,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:V,useExisting:a((()=>on)),multi:!0},{provide:w,useExisting:a((()=>on)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n {{ hintText }}\n \n
\n
\n
\n \n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),Me([h()],on.prototype,"disabled",void 0),Me([h()],on.prototype,"uniqueKeyValuePairValidator",void 0),Me([h()],on.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:on,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:V,useExisting:a((()=>on)),multi:!0},{provide:w,useExisting:a((()=>on)),multi:!0}],template:'
\n
\n \n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n {{ hintText }}\n \n
\n
\n
\n \n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class an{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne}ngOnInit(){this.slideToggleControlGroup=this.fb.group({slideToggleControl:[null,[]]}),this.slideToggleControlGroup.get("slideToggleControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.slideToggleControlGroup.get("slideToggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SlideToggleComponent",an),an.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:an,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),an.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:an,selector:"tb-slide-toggle",inputs:{slideToggleName:"slideToggleName",slideToggleTooltip:"slideToggleTooltip"},providers:[{provide:V,useExisting:a((()=>an)),multi:!0}],ngImport:t,template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"],dependencies:[{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:De.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:an,decorators:[{type:n,args:[{selector:"tb-slide-toggle",providers:[{provide:V,useExisting:a((()=>an)),multi:!0}],template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{slideToggleName:[{type:i}],slideToggleTooltip:[{type:i}]}});class ln extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[E.min(1)]],relationType:[null],deviceTypes:[null,[E.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",ln),ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ln,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ln,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>ln)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ge.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["label","required","disabled","entityType"]},{kind:"component",type:Ee.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","required","disabled","subscriptSizing"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ln,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:V,useExisting:a((()=>ln)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class sn{set required(e){this.requiredValue=pe(e)}get required(){return this.requiredValue}}e("FieldsetComponent",sn),sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sn,deps:[],target:t.ɵɵFactoryTarget.Component}),sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:sn,selector:"tb-fieldset-component",inputs:{label:"label",required:"required"},ngImport:t,template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sn,decorators:[{type:n,args:[{selector:"tb-fieldset-component",template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],propDecorators:{label:[{type:i}],required:[{type:i}]}});class mn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[E.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",mn),mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:mn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>mn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ve.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:V,useExisting:a((()=>mn)),multi:!0}],template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class un extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.message-type",this.separatorKeysCodes=[oe,ae,ie],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(C))this.messageTypesList.push({name:v.get(C[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchMessageTypes(e))),Fe())}ngAfterViewInit(){}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return!!(e&&null!=e&&e.length>0)}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ie(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t=null;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:un,deps:[{token:A.Store},{token:_.TranslateService},{token:F.TruncatePipe},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:un,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:V,useExisting:a((()=>un)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:V,useExisting:a((()=>un)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ translate.get(\'tb.rulenode.no-message-type-matching\',\n {messageType: truncate.transform(searchText, true, 6, '...')}) }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:F.TruncatePipe},{type:G.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class pn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRquired=!0,this.allCredentialsTypes=Lt,this.credentialsTypeTranslationsMap=kt,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[E.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.pipe(Le()).subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){X(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators(!1))}setDisabledState(e){e?this.credentialsConfigFormGroup.disable():(this.credentialsConfigFormGroup.enable(),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([E.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRquired?[E.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(E.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",pn),pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:pn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRquired:"passwordFieldRquired"},providers:[{provide:V,useExisting:a((()=>pn)),multi:!0},{provide:w,useExisting:a((()=>pn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:O.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:O.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Se.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:pn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:V,useExisting:a((()=>pn)),multi:!0},{provide:w,useExisting:a((()=>pn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRquired:[{type:i}]}});class dn{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne,this.fetchTo=Dt}ngOnInit(){this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("MsgMetadataChipComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:dn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText"},providers:[{provide:V,useExisting:a((()=>dn)),multi:!0}],ngImport:t,template:'
\n \n \n {{ \'tb.rulenode.message\' | translate }}\n {{ \'tb.rulenode.metadata\' | translate }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"],dependencies:[{kind:"component",type:se.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:se.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:V,useExisting:a((()=>dn)),multi:!0}],template:'
\n \n \n {{ \'tb.rulenode.message\' | translate }}\n {{ \'tb.rulenode.metadata\' | translate }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{labelText:[{type:i}]}});class cn extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new Ne,this.sourceFieldSubcritption=[],this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(D),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({}),this.svListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[E.required]],value:[e[n],[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.svListFormGroup.setControl("keyVals",this.fb.array(t));for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e);this.valueChangeSubscription=this.svListFormGroup.valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.updateModel()}))}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value)t.push(this.selectOptions.find((t=>t===e.key)));const n=[];for(const r of this.selectOptions)X(t.find((e=>e===r)))&&r!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.svListFormGroup.get("keyVals").removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){const e=this.svListFormGroup.get("keyVals");e.push(this.fb.group({key:["",[E.required]],value:["",[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(e.controls[e.length-1])}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(Ce(this.destroy$)).subscribe((t=>{e.get("value").patchValue(this.targetKeyPrefix+t[0].toUpperCase()+t.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cn,deps:[{token:A.Store},{token:_.TranslateService},{token:t.Injector},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:cn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",selectOptionsTranslate:"selectOptionsTranslate",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:V,useExisting:a((()=>cn)),multi:!0},{provide:w,useExisting:a((()=>cn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n \n {{ selectText }}\n \n \n {{selectOptionsTranslate.get(option) | translate}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n {{ hintText }}\n \n
\n
\n
\n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:fe.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),Me([h()],cn.prototype,"disabled",void 0),Me([h()],cn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:V,useExisting:a((()=>cn)),multi:!0},{provide:w,useExisting:a((()=>cn)),multi:!0}],template:'
\n
\n \n
\n
\n
\n \n {{ selectText }}\n \n \n {{selectOptionsTranslate.get(option) | translate}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n {{ hintText }}\n \n
\n
\n
\n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:t.Injector},{type:G.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],selectOptionsTranslate:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class fn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=pe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[E.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:fn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:V,useExisting:a((()=>fn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ve.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:V,useExisting:a((()=>fn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class gn{set enableFieldToggle(e){this._enableFieldToggle=pe(e)}get enableFieldToggle(){return this._enableFieldToggle}constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Ne,this.DataToFetch=ht}ngOnInit(){this.toggleControlGroup=this.fb.group({toggleControl:[null,[]]}),this.toggleControlGroup.get("toggleControl").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.toggleControlGroup.get("toggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("FetchToDataToggleComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:gn,selector:"tb-fetch-to-data-toggle",inputs:{enableFieldToggle:"enableFieldToggle"},providers:[{provide:V,useExisting:a((()=>gn)),multi:!0}],ngImport:t,template:'
\n \n {{ \'tb.rulenode.attributes\' | translate }}\n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n {{ \'tb.rulenode.fields\' | translate }}\n \n
\n',styles:[":host ::ng-deep{margin-bottom:12px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;width:215px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Re.MatButtonToggleGroup,selector:"mat-button-toggle-group",inputs:["appearance","name","vertical","value","multiple","disabled"],outputs:["valueChange","change"],exportAs:["matButtonToggleGroup"]},{kind:"component",type:Re.MatButtonToggle,selector:"mat-button-toggle",inputs:["disableRipple","aria-label","aria-labelledby","id","name","value","tabIndex","appearance","checked","disabled"],outputs:["change"],exportAs:["matButtonToggle"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-fetch-to-data-toggle",providers:[{provide:V,useExisting:a((()=>gn)),multi:!0}],template:'
\n \n {{ \'tb.rulenode.attributes\' | translate }}\n {{ \'tb.rulenode.latest-telemetry\' | translate }}\n {{ \'tb.rulenode.fields\' | translate }}\n \n
\n',styles:[":host ::ng-deep{margin-bottom:12px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;width:215px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]},propDecorators:{enableFieldToggle:[{type:i}]}});class yn{constructor(e,t,n){this.store=e,this.translate=t,this.fb=n,this.destroy$=new Ne,this.separatorKeysCodes=[oe,ae,ie]}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[null,[]],sharedAttributeNames:[null,[]],serverAttributeNames:[null,[]],latestTsKeyNames:[null,[]],getLatestValueWithTs:[!1,[]]}),this.attributeControlGroup.valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.attributeControlGroup.patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}removeKey(e,t){const n=this.attributeControlGroup.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.attributeControlGroup.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.attributeControlGroup.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.attributeControlGroup.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}clearChipGrid(e){this.attributeControlGroup.get(e).patchValue([],{emitEvent:!0})}}e("SelectAttributesComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:yn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:V,useExisting:a((()=>yn)),multi:!0}],ngImport:t,template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin:10px 0 12px;display:block}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:V,useExisting:a((()=>yn)),multi:!0}],template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin:10px 0 12px;display:block}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class xn{}e("RulenodeCoreConfigCommonModule",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),xn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:xn,declarations:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn],imports:[H,L,qe],exports:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn]}),xn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,imports:[H,L,qe]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:xn,decorators:[{type:l,args:[{declarations:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn],imports:[H,L,qe],exports:[on,ln,mn,un,pn,Qe,Zt,en,nn,Qt,dn,an,cn,sn,fn,gn,yn]}]}]});class bn{}e("RuleNodeCoreConfigActionModule",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),bn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:bn,declarations:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn],imports:[H,L,qe,xn],exports:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn]}),bn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,imports:[H,L,qe,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:bn,decorators:[{type:l,args:[{declarations:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn],imports:[H,L,qe,xn],exports:[Xt,Ye,Yt,$t,Kt,Je,Xe,Ze,et,Ut,tt,rt,Ht,Bt,jt,Jt,Wt,We,nt,_t,zt,tn,rn]}]}]});class hn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[E.min(0),E.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:X(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:X(e?.outputValueKey)?e.outputValueKey:null,useCache:!X(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!X(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:X(e?.periodValueKey)?e.periodValueKey:null,round:X(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!X(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return e.inputValueKey=e.inputValueKey.trim(),e.outputValueKey=e.outputValueKey.trim(),e}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([E.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:hn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Cn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n].trim();return e.dataMapping=t,e}prepareInputConfig(e){let t,n;return t=X(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Cn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class vn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[E.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return Z(e)&&(e.attributesControl={clientAttributeNames:X(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:X(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:X(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!X(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:X(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!X(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:vn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ln,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:yn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Fn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.entityDetailsTranslationsMap=gt,this.entityDetailsList=[],this.searchText="",this.displayDetailsFn=this.displayDetails.bind(this);for(const e of Object.keys(dt))this.entityDetailsList.push(dt[e]);this.detailsFormControl=new P(""),this.filteredEntityDetails=this.detailsFormControl.valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchEntityDetails(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return this.searchText="",this.detailsFormControl.patchValue("",{emitEvent:!0}),this.detailsList=e?e.detailsList:[],t=X(e?.addToMetadata)?e.addToMetadata?Dt.METADATA:Dt.DATA:e?.fetchTo?e.fetchTo:Dt.DATA,{detailsList:X(e?.detailsList)?e.detailsList:null,fetchTo:t}}prepareOutputConfig(e){return e.detailsList=this.detailsList,e}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[E.required]],fetchTo:[e.fetchTo,[]]}),this.detailsList=e?e.detailsList:[]}displayDetails(e){return e?this.translate.instant(gt.get(e)):void 0}fetchEntityDetails(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(this.entityDetailsList.filter((t=>this.translate.instant(gt.get(dt[t])).toUpperCase().includes(e))))}return Ie(this.entityDetailsList)}detailsFieldSelected(e){this.addDetailsField(e.option.value),this.clear("")}removeDetailsField(e){const t=this.detailsList.indexOf(e);t>=0&&(this.detailsList.splice(t,1),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}addDetailsField(e){this.detailsList||(this.detailsList=[]);-1===this.detailsList.indexOf(e)&&(this.detailsList.push(e),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}onEntityDetailsInputFocus(){this.detailsFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clearChipGrid(){this.detailsList=[],this.entityDetailsConfigForm.get("detailsList").patchValue([],{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}clear(e=""){this.detailsInput.nativeElement.value=e,this.detailsFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}}e("EntityDetailsConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Fn,selector:"tb-enrichment-node-entity-details-config",viewQueries:[{propertyName:"detailsInput",first:!0,predicate:["detailsInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]},propDecorators:{detailsInput:[{type:o,args:["detailsInput",{static:!1}]}]}});class Ln extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[oe,ae,ie],this.aggregationTypes=k,this.aggregations=Object.keys(k),this.aggregationTypesTranslations=T,this.fetchMode=yt,this.fetchModes=Object.keys(yt),this.deduplicationStrategiesTranslations=xt,this.samplingOrders=Object.keys(bt),this.samplingOrdersTranslate=Ct,this.timeUnits=Object.values(st),this.timeUnitsTranslationMap=mt,this.timeUnitMap={[st.MILLISECONDS]:1,[st.SECONDS]:1e3,[st.MINUTES]:6e4,[st.HOURS]:36e5,[st.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[]],aggregation:[e.aggregation,[E.required]],fetchMode:[e.fetchMode,[E.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,e.startIntervalPattern=e.startIntervalPattern.trim(),e.endIntervalPattern=e.endIntervalPattern.trim(),delete e.interval,e}prepareInputConfig(e){return Z(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:X(e?.aggregation)?e.aggregation:k.NONE,fetchMode:X(e?.fetchMode)?e.fetchMode:yt.FIRST,orderBy:X(e?.orderBy)?e.orderBy:bt.ASC,limit:X(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!X(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:X(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:X(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:st.MINUTES,endInterval:X(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:X(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:st.MINUTES},startIntervalPattern:X(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:X(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===yt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([E.required,E.min(2),E.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([E.required,E.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([E.required,E.min(1),E.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([E.required,E.min(1),E.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([E.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}fetchModeHintSelector(){let e;switch(this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value){case yt.ALL:e="tb.rulenode.all-mode-hint";break;case yt.LAST:e="tb.rulenode.last-mode-hint";break;case yt.FIRST:e="tb.rulenode.first-mode-hint"}return e}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}}e("GetTelemetryFromDatabaseConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ln,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Ln,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n {{ deduplicationStrategiesTranslations.get(fetchMode) | translate}}\n \n
\n {{ fetchModeHintSelector() | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle mat-button-toggle{width:215px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .additional-inputs{margin-bottom:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ae.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:ne.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:Re.MatButtonToggleGroup,selector:"mat-button-toggle-group",inputs:["appearance","name","vertical","value","multiple","disabled"],outputs:["valueChange","change"],exportAs:["matButtonToggleGroup"]},{kind:"component",type:Re.MatButtonToggle,selector:"mat-button-toggle",inputs:["disableRipple","aria-label","aria-labelledby","id","name","value","tabIndex","appearance","checked","disabled"],outputs:["change"],exportAs:["matButtonToggle"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n {{ deduplicationStrategiesTranslations.get(fetchMode) | translate}}\n \n
\n {{ fetchModeHintSelector() | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle mat-button-toggle{width:215px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .additional-inputs{margin-bottom:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard{border:none;border-radius:18px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle{background:#f0f0f0;height:32px;align-items:center;display:flex}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle .mat-button-toggle-ripple{inset:2px;border-radius:16px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-button{height:32px;color:#959595}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-focus-overlay{border-radius:16px;margin:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked .mat-button-toggle-button{background-color:#305680;color:#fff;border-radius:16px;margin-left:2px;margin-right:2px}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{line-height:20px;font-size:14px;font-weight:500}:host ::ng-deep .mat-button-toggle-group.tb-script-lang-toggle-group .mat-button-toggle-checked.mat-button-toggle-appearance-standard:not(.mat-button-toggle-disabled):hover .mat-button-toggle-focus-overlay{opacity:.01}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class kn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return Z(e)&&(e.attributesControl={clientAttributeNames:X(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:X(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:X(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:X(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!X(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA,tellFailureIfAbsent:!!X(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:X(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kn,deps:[{token:A.Store},{token:_.TranslateService},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:kn,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:yn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.FormBuilder}]}});class Tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorFields=[],this.originatorFieldsTranslations=ft;for(const e of Object.keys(ct))this.originatorFields.push(ct[e])}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){for(const t of Object.keys(e.dataMapping))e.dataMapping[t]=e.dataMapping[t].trim();return e}prepareInputConfig(e){return{dataMapping:X(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:X(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[E.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Tn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"],dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:an,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:cn,selector:"tb-sv-map-config",inputs:["selectOptions","selectOptionsTranslate","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class In extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht,this.originatorFieldsTranslations=ft,this.originatorFields=[],this.destroy$=new Ne,this.defaultKvMap={serialNumber:"sn"},this.defaultSvMap={name:"relatedEntityName"},this.dataToFetchPrevValue="";for(const e of Object.keys(ct))this.originatorFields.push(ct[e])}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n].trim();return e.dataMapping=t,e}prepareInputConfig(e){let t;return X(e?.telemetry)?this.dataToFetchPrevValue=e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:this.dataToFetchPrevValue=X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,t=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{relationsQuery:X(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:this.dataToFetchPrevValue,dataMapping:t,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[E.required]],dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo,[]]}),this.relatedAttributesConfigForm.get("dataToFetch").valueChanges.pipe(Ce(this.destroy$)).subscribe((e=>{e===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultSvMap,{emitEvent:!1}),e!==ht.FIELDS&&this.dataToFetchPrevValue===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultKvMap,{emitEvent:!1}),this.dataToFetchPrevValue=e}))}msgMetadataChipLabel(){switch(this.relatedAttributesConfigForm.get("dataToFetch").value){case ht.ATTRIBUTES:return"tb.rulenode.add-mapped-attribute-to";case ht.LATEST_TELEMETRY:return"tb.rulenode.add-mapped-latest-telemetry-to";case ht.FIELDS:return"tb.rulenode.add-mapped-fields-to"}}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("RelatedAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:In,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:In,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:mn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:cn,selector:"tb-sv-map-config",inputs:["selectOptions","selectOptionsTranslate","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Nn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.DataToFetch=ht}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=X(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:X(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=X(e?.attrMapping)?e.attrMapping:X(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[E.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Nn,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:on,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:sn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:gn,selector:"tb-fetch-to-data-toggle",inputs:["enableFieldToggle"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Sn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:X(e?.fetchTo)?e.fetchTo:Dt.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sn,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Sn,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:dn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class qn{}e("RulenodeCoreConfigEnrichmentModule",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),qn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:qn,declarations:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn],imports:[H,L,xn],exports:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn]}),qn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:qn,decorators:[{type:l,args:[{declarations:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn],imports:[H,L,xn],exports:[Cn,Fn,vn,kn,Tn,Ln,In,Nn,hn,Sn]}]}]});class Mn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Tt,this.azureIotHubCredentialsTypeTranslationsMap=It}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[E.required,E.min(1),E.max(200)]],clientId:[e?e.clientId:null,[E.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[E.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([E.required]);break;case"cert.PEM":t.get("privateKey").setValidators([E.required]),t.get("privateKeyFileName").setValidators([E.required]),t.get("cert").setValidators([E.required]),t.get("certFileName").setValidators([E.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Mn,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:O.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:O.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Se.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Se.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Se.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Se.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Se.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:G.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class An extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=St,this.ToByteStandartCharsetTypeTranslationMap=qt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[E.required]],retries:[e?e.retries:null,[E.min(0)]],batchSize:[e?e.batchSize:null,[E.min(0)]],linger:[e?e.linger:null,[E.min(0)]],bufferMemory:[e?e.bufferMemory:null,[E.min(0)]],acks:[e?e.acks:null,[E.required]],keySerializer:[e?e.keySerializer:null,[E.required]],valueSerializer:[e?e.valueSerializer:null,[E.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([E.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:An,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:An,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Gn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[]}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[E.required]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[E.required,E.min(1),E.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ee(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]}),this.subscriptions.push(this.mqttConfigForm.get("clientId").valueChanges.subscribe((e=>{ee(e)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1})})))}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}}e("MqttConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Gn,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:pn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRquired"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class En extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=I,this.entityType=x}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[E.required]],targets:[e?e.targets:[],[E.required]]})}}e("NotificationConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:En,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:En,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:Oe.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:He.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","disabled","notificationTypes"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Dn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[E.required]],topicName:[e?e.topicName:null,[E.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[E.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[E.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Dn,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:we.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Vn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[E.required]],port:[e?e.port:null,[E.required,E.min(1),E.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[E.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[E.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Vn,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class wn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(Nt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[E.required]],requestMethod:[e?e.requestMethod:null,[E.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],trimDoubleQuotes:[!!e&&e.trimDoubleQuotes,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[E.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[E.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[E.required,E.min(1),E.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([E.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([E.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",wn),wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:wn,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:pn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRquired"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:wn,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Pn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([E.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([E.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([E.required,E.min(1),E.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([E.required,E.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[E.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[E.required,E.min(1),E.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",Pn),Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Pn,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ke.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:U.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Pe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Pn,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[E.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[E.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([E.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Rn,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Be.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class On extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(N),this.slackChanelTypesTranslateMap=S}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[E.required]],conversationType:[e?e.conversationType:null,[E.required]],conversation:[e?e.conversation:null,[E.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([E.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:On,deps:[{token:A.Store},{token:G.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:On,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ze.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.FormBuilder}]}});class Hn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[E.required]],accessKeyId:[e?e.accessKeyId:null,[E.required]],secretAccessKey:[e?e.secretAccessKey:null,[E.required]],region:[e?e.region:null,[E.required]]})}}e("SnsConfigComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Hn,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Kn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=vt,this.sqsQueueTypes=Object.keys(vt),this.sqsQueueTypeTranslationsMap=Ft}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[E.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[E.required]],delaySeconds:[e?e.delaySeconds:null,[E.min(0),E.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[E.required]],secretAccessKey:[e?e.secretAccessKey:null,[E.required]],region:[e?e.region:null,[E.required]]})}}e("SqsConfigComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Kn,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Bn{}e("RulenodeCoreConfigExternalModule",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Bn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Bn,declarations:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On],imports:[H,L,qe,xn],exports:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On]}),Bn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,imports:[H,L,qe,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Bn,decorators:[{type:l,args:[{declarations:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On],imports:[H,L,qe,xn],exports:[Hn,Kn,Dn,An,Gn,En,Vn,wn,Pn,Mn,Rn,On]}]}]});class Un extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.alarmStatusTranslationsMap=q,this.alarmStatusList=[],this.searchText="",this.displayStatusFn=this.displayStatus.bind(this);for(const e of Object.keys(M))this.alarmStatusList.push(M[e]);this.statusFormControl=new R(""),this.filteredAlarmStatus=this.statusFormControl.valueChanges.pipe(ve(""),be((e=>e||"")),he((e=>this.fetchAlarmStatus(e))),Fe())}ngOnInit(){super.ngOnInit()}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return this.searchText="",this.statusFormControl.patchValue("",{emitEvent:!0}),e}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e?e.alarmStatusList:null,[E.required]]})}displayStatus(e){return e?this.translate.instant(q.get(e)):void 0}fetchAlarmStatus(e){const t=this.getAlarmStatusList();if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ie(t.filter((t=>this.translate.instant(q.get(M[t])).toUpperCase().includes(e))))}return Ie(t)}alarmStatusSelected(e){this.addAlarmStatus(e.option.value),this.clear("")}removeAlarmStatus(e){const t=this.alarmStatusConfigForm.get("alarmStatusList").value;if(t){const n=t.indexOf(e);n>=0&&(t.splice(n,1),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}}addAlarmStatus(e){let t=this.alarmStatusConfigForm.get("alarmStatusList").value;t||(t=[]);-1===t.indexOf(e)&&(t.push(e),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}getAlarmStatusList(){return this.alarmStatusList.filter((e=>-1===this.alarmStatusConfigForm.get("alarmStatusList").value.indexOf(e)))}onAlarmStatusInputFocus(){this.statusFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.alarmStatusInput.nativeElement.value=e,this.statusFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.alarmStatusInput.nativeElement.blur(),this.alarmStatusInput.nativeElement.focus()}),0)}}e("CheckAlarmStatusComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Un,deps:[{token:A.Store},{token:_.TranslateService},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Un,selector:"tb-filter-node-check-alarm-status-config",viewQueries:[{propertyName:"alarmStatusInput",first:!0,predicate:["alarmStatusInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ke.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:ke.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:ke.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:O.AsyncPipe,name:"async"},{kind:"pipe",type:Te.HighlightPipe,name:"highlight"},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:_.TranslateService},{type:G.UntypedFormBuilder}]},propDecorators:{alarmStatusInput:[{type:o,args:["alarmStatusInput",{static:!1}]}]}});class zn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}configForm(){return this.checkMessageConfigForm}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e?e.messageNames:null,[]],metadataNames:[e?e.metadataNames:null,[]],checkAllKeys:[!!e&&e.checkAllKeys,[]]})}validateConfig(){const e=this.checkMessageConfigForm.get("messageNames").value,t=this.checkMessageConfigForm.get("metadataNames").value;return e.length>0||t.length>0}removeMessageName(e){const t=this.checkMessageConfigForm.get("messageNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("messageNames").setValue(t,{emitEvent:!0}))}removeMetadataName(e){const t=this.checkMessageConfigForm.get("metadataNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("metadataNames").setValue(t,{emitEvent:!0}))}addMessageName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("messageNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("messageNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}addMetadataName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("metadataNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("metadataNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CheckMessageConfigComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:zn,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class _n extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.keys(g),this.entitySearchDirectionTranslationsMap=y}configForm(){return this.checkRelationConfigForm}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[!!e&&e.checkForSingleEntity,[]],direction:[e?e.direction:null,[]],entityType:[e?e.entityType:null,e&&e.checkForSingleEntity?[E.required]:[]],entityId:[e?e.entityId:null,e&&e.checkForSingleEntity?[E.required]:[]],relationType:[e?e.relationType:null,[E.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[E.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[E.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_n,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:_n,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:_e.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Ee.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","required","disabled","subscriptSizing"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class jn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=it,this.perimeterTypes=Object.keys(it),this.perimeterTypeTranslationMap=lt,this.rangeUnits=Object.keys(ut),this.rangeUnitTranslationMap=pt}configForm(){return this.geoFilterConfigForm}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[E.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[E.required]],perimeterType:[e?e.perimeterType:null,[E.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([E.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==it.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([])):(this.geoFilterConfigForm.get("centerLatitude").setValidators([E.required,E.min(-90),E.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([E.required,E.min(-180),E.max(180)]),this.geoFilterConfigForm.get("range").setValidators([E.required,E.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([E.required])),t||n!==it.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([E.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:jn,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:K.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:G.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class $n extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e?e.messageTypes:null,[E.required]]})}}e("MessageTypeConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$n,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:$n,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:un,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Qn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.TENANT,x.CUSTOMER,x.USER,x.DASHBOARD,x.RULE_CHAIN,x.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e?e.originatorTypes:null,[E.required]]})}}e("OriginatorTypeConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Qn,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n
\n',dependencies:[{kind:"component",type:je.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","disabled","subscriptSizing","allowedEntityTypes","ignoreAuthorityFilter"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Jn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Jn,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Yn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.switchConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",r=this.switchConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.switchConfigForm.get(t).setValue(e)}))}onValidate(){this.switchConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Yn,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Wn{}e("RuleNodeCoreConfigFilterModule",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Wn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:Wn,declarations:[zn,_n,jn,$n,Qn,Jn,Yn,Un],imports:[H,L,xn],exports:[zn,_n,jn,$n,Qn,Jn,Yn,Un]}),Wn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Wn,decorators:[{type:l,args:[{declarations:[zn,_n,jn,$n,Qn,Jn,Yn,Un],imports:[H,L,xn],exports:[zn,_n,jn,$n,Qn,Jn,Yn,Un]}]}]});class Xn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=ot,this.originatorSources=Object.keys(ot),this.originatorSourceTranslationMap=at,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.USER,x.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[E.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===ot.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([E.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===ot.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([E.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([E.required,E.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xn,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Xn,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fn,selector:"tb-relations-query-config-old",inputs:["disabled","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class Zn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=Y(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[E.required]],jsScript:[e?e.jsScript:null,[E.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[E.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[E.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zn,deps:[{token:A.Store},{token:G.UntypedFormBuilder},{token:W.NodeScriptTestService},{token:_.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:Zn,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:te.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ne.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder},{type:W.NodeScriptTestService},{type:_.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",value:"false"},{name:"tb.mail-body-type.html",value:"true"},{name:"tb.mail-body-type.dynamic",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[E.required]],toTemplate:[e?e.toTemplate:null,[E.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[E.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null],bodyTemplate:[e?e.bodyTemplate:null,[E.required]]}),this.toEmailConfigForm.get("mailBodyType").valueChanges.pipe(ve([e?.subjectTemplate])).subscribe((e=>{"dynamic"===e?(this.toEmailConfigForm.get("isHtmlTemplate").patchValue("",{emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").setValidators(E.required)):this.toEmailConfigForm.get("isHtmlTemplate").clearValidators(),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity()}))}}e("ToEmailConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:er,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:$.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:Q.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:_.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class tr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],keys:[e?e.keys:null,[E.required]]})}configForm(){return this.copyKeysConfigForm}removeKey(e){const t=this.copyKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.copyKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.copyKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.copyKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CopyKeysConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:tr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class nr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[E.required]]})}}e("RenameKeysConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:nr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Qt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[E.required]]})}}e("NodeJsonPathConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:rr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n",dependencies:[{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatLabel,selector:"mat-label"},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n"}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class or extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[oe,ae,ie]}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[E.required]],keys:[e?e.keys:null,[E.required]]})}configForm(){return this.deleteKeysConfigForm}removeKey(e){const t=this.deleteKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteKeysConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:le.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:B.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:U.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:U.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:U.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ue.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:Ue.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:se.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:se.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:se.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:se.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"},{kind:"pipe",type:Qe,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class ar{}e("RulenodeCoreConfigTransformModule",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ar.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:ar,declarations:[Xn,Zn,er,tr,nr,rr,or],imports:[H,L,xn],exports:[Xn,Zn,er,tr,nr,rr,or]}),ar.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ar,decorators:[{type:l,args:[{declarations:[Xn,Zn,er,tr,nr,rr,or],imports:[H,L,xn],exports:[Xn,Zn,er,tr,nr,rr,or]}]}]});class ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=x}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[E.required]]})}}e("RuleChainInputComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:ir,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:_e.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:G.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class lr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,deps:[{token:A.Store},{token:G.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.5",type:lr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:G.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:G.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:_.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:A.Store},{type:G.UntypedFormBuilder}]}});class sr{}e("RuleNodeCoreConfigFlowModule",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),sr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:sr,declarations:[ir,lr],imports:[H,L,xn],exports:[ir,lr]}),sr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,imports:[H,L,xn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:sr,decorators:[{type:l,args:[{declarations:[ir,lr],imports:[H,L,xn],exports:[ir,lr]}]}]});class mr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{"create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","output-message-type":"Output message type","output-message-type-required":"Output message type is required","output-message-type-max-length":"Output message type should be less than 256","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. In case you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required!","limit-range":"Limit should be in a range from 2 to 1000!","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Time value should be in a range from 1 to 2147483647!","start-interval-value-required":"Start interval value is required!","end-interval-value-required":"End interval value is required!",filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Notify device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-hint":"If the message arrives from the device, we will push it back to the device by default.","notify-device-delete-hint":"Send notification about deleted attributes to device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","add-timeseries-key":"Add timeseries key","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Hint: use regular expression to copy keys by pattern",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","key-name":"Key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Max relation level should be greater than 0 or unspecified!","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required!","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required!","target-key":"Target key","target-key-required":"Target key is required!","attr-mapping-required":"At least one mapping entry should be specified!","fields-mapping":"Fields mapping*","fields-mapping-required":"At least one field mapping should be specified.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","source-field":"Source field","source-field-required":"Source field is required!","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","body-template":"Body Template","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","trim-double-quotes":"Message without quotes","trim-double-quotes-hint":"If selected, request body message payload will be sent without double quotes, i.e. msg = message body","read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Hint: Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Hint: Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Hint: Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required!","end-interval-required":"Interval end is required!","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"entity-details":"Select entity details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","entity-details-list-empty":"No entity details selected!","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-key-name":"Latitude key name","longitude-key-name":"Longitude key name","latitude-key-name-required":"Latitude key name is required.","longitude-key-name-required":"Longitude key name is required.","fetch-perimeter-info-from-message-metadata":"Fetch perimeter information from message metadata","perimeter-key-name":"Perimeter key name","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Please, use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required!","output-value-key":"Output value key","output-value-key-required":"Output value key is required!","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15!","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-cashing":"Use cashing","use-cashing-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required!","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time series","message-body-type":"Message body","message-metadata-type":"Message metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-type-field-input":"Type","argument-type-field-input-required":"Argument type is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Hint: use 0 to convert result to integer","add-to-body-field-input":"Add to message body","add-to-metadata-field-input":"Add to message metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Hint: specify a mathematical expression to evaluate. For example, transform Fahrenheit to Celsius using (x - 32) / 1.8)","retained-message":"Retained","attributes-mapping":"Attributes mapping*","latest-telemetry-mapping":"Latest telemetry mapping*","add-mapped-attribute-to":"Add mapped attributes to:","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to:","add-mapped-fields-to":"Add mapped fields to:","add-selected-details-to":"Add selected details to:","clear-selected-details":"Clear selected details","clear-selected-keys":"Clear selected keys","fetch-credentials-to":"Fetch credentials to:","add-originator-attributes-to":"Add originator attributes to:","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound message metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell Failure","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to:",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output message metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end")!',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch:","mapping-of-customers":"Mapping of customer's:",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to:","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's:","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required"},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping entry","add-entry":"Add entry","unique-key-value-pair-error":"'{{valText}}' must be different from the current '{{keyText}}'"},"mail-body-type":{"plain-text":"Plain Text",html:"HTML",dynamic:"Dynamic"}}},!0)}(e)}}e("RuleNodeCoreConfigModule",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,deps:[{token:_.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),mr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.5",ngImport:t,type:mr,declarations:[$e],imports:[H,L],exports:[bn,Wn,qn,Bn,ar,sr,$e]}),mr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,imports:[H,L,bn,Wn,qn,Bn,ar,sr]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.5",ngImport:t,type:mr,decorators:[{type:l,args:[{declarations:[$e],imports:[H,L],exports:[bn,Wn,qn,Bn,ar,sr,$e]}]}],ctorParameters:function(){return[{type:_.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map +System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/platform-browser","@angular/material/select","@angular/material/core","@shared/components/queue/queue-autocomplete.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/icon","@angular/material/chips","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/material/tooltip","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","rxjs","@angular/material/expansion","@home/components/public-api","tslib","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@angular/material/slide-toggle","@home/components/relation/relation-filters.component","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@shared/components/toggle-header.component","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,u,p,d,c,f,g,y,x,b,h,C,v,F,L,k,T,I,N,S,q,M,A,G,E,D,V,w,P,R,O,H,K,B,U,z,_,j,$,Q,J,Y,W,X,Z,ee,te,ne,re,oe,ae,ie,le,se,me,ue,pe,de,ce,fe,ge,ye,xe,be,he,Ce,ve,Fe,Le,ke,Te,Ie,Ne,Se,qe,Me,Ae,Ge,Ee,De,Ve,we,Pe,Re,Oe,He,Ke,Be,Ue,ze,_e,je,$e;return{setters:[function(e){t=e,n=e.Component,r=e.Pipe,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.NgModule},function(e){s=e.RuleNodeConfigurationComponent,m=e.AttributeScope,u=e.telemetryTypeTranslations,p=e.ServiceType,d=e.ScriptLanguage,c=e.AlarmSeverity,f=e.alarmSeverityTranslations,g=e.EntitySearchDirection,y=e.entitySearchDirectionTranslations,x=e.EntityType,b=e.PageComponent,h=e.coerceBoolean,C=e.MessageType,v=e.messageTypeNames,F=e,L=e.SharedModule,k=e.AggregationType,T=e.aggregationTranslations,I=e.entityFields,N=e.NotificationType,S=e.SlackChanelType,q=e.SlackChanelTypesTranslateMap,M=e.alarmStatusTranslations,A=e.AlarmStatus},function(e){G=e},function(e){E=e,D=e.Validators,V=e.NgControl,w=e.NG_VALUE_ACCESSOR,P=e.NG_VALIDATORS,R=e.FormControl,O=e.UntypedFormControl},function(e){H=e,K=e.CommonModule},function(e){B=e},function(e){U=e},function(e){z=e},function(e){_=e},function(e){j=e},function(e){$=e},function(e){Q=e},function(e){J=e},function(e){Y=e},function(e){W=e.getCurrentAuthState,X=e,Z=e.isDefinedAndNotNull,ee=e.deepTrim,te=e.isObject,ne=e.isNotEmptyStr},function(e){re=e},function(e){oe=e},function(e){ae=e},function(e){ie=e.ENTER,le=e.COMMA,se=e.SEMICOLON},function(e){me=e},function(e){ue=e},function(e){pe=e},function(e){de=e},function(e){ce=e.coerceBooleanProperty},function(e){fe=e},function(e){ge=e},function(e){ye=e},function(e){xe=e},function(e){be=e},function(e){he=e.tap,Ce=e.map,ve=e.mergeMap,Fe=e.takeUntil,Le=e.startWith,ke=e.share},function(e){Te=e},function(e){Ie=e},function(e){Ne=e.of,Se=e.Subject},function(e){qe=e},function(e){Me=e.HomeComponentsModule},function(e){Ae=e.__decorate},function(e){Ge=e},function(e){Ee=e},function(e){De=e},function(e){Ve=e},function(e){we=e},function(e){Pe=e},function(e){Re=e},function(e){Oe=e},function(e){He=e},function(e){Ke=e},function(e){Be=e},function(e){Ue=e},function(e){ze=e},function(e){_e=e},function(e){je=e},function(e){$e=e}],execute:function(){class Qe extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",Qe),Qe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qe,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Qe,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qe,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Je{constructor(e){this.sanitizer=e}transform(e){return this.sanitizer.bypassSecurityTrustHtml(e)}}e("SafeHtmlPipe",Je),Je.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Je,deps:[{token:$.DomSanitizer}],target:t.ɵɵFactoryTarget.Pipe}),Je.ɵpipe=t.ɵɵngDeclarePipe({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Je,name:"safeHtml"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Je,decorators:[{type:r,args:[{name:"safeHtml"}]}],ctorParameters:function(){return[{type:$.DomSanitizer}]}});class Ye extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[D.required,D.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[D.required,D.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",Ye),Ye.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ye,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ye.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ye,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ye,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class We extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[D.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===m.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",We),We.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:We,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),We.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:We,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:We,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-hint
\n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
tb.rulenode.send-attributes-updated-notification-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Xe extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.checkPointConfigForm}onConfigurationSet(e){this.checkPointConfigForm=this.fb.group({queueName:[e?e.queueName:null,[D.required]]})}}e("CheckPointConfigComponent",Xe),Xe.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xe,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xe.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Xe,selector:"tb-action-node-check-point-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:Y.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xe,decorators:[{type:n,args:[{selector:"tb-action-node-check-point-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Ze extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=W(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[D.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[D.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===d.JS?[D.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===d.TBEL?[D.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.clearAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",r=this.clearAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.clearAlarmConfigForm.get(t).setValue(e)}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",Ze),Ze.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ze,deps:[{token:G.Store},{token:E.UntypedFormBuilder},{token:X.NodeScriptTestService},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ze.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ze,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:re.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ae.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ze,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder},{type:X.NodeScriptTestService},{type:j.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class et extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.alarmSeverities=Object.keys(c),this.alarmSeverityTranslationMap=f,this.separatorKeysCodes=[ie,le,se],this.tbelEnabled=W(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[D.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([D.required]),this.createAlarmConfigForm.get("severity").setValidators([D.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==d.TBEL||this.tbelEnabled||(r=d.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===d.JS?[D.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===d.TBEL?[D.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.createAlarmConfigForm.get("scriptLang").value,t=e===d.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",n=e===d.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",r=this.createAlarmConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.createAlarmConfigForm.get(t).setValue(e)}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",et),et.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:et,deps:[{token:G.Store},{token:E.UntypedFormBuilder},{token:X.NodeScriptTestService},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),et.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:et,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:re.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ae.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:et,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder},{type:X.NodeScriptTestService},{type:j.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class tt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[D.required]],entityType:[e?e.entityType:null,[D.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[D.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[D.required,D.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([D.required,D.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==x.DEVICE&&t!==x.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([D.required,D.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",tt),tt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:tt,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tt,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class nt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[D.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[D.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[D.required,D.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([D.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([D.required,D.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",nt),nt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:nt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class rt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,D.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,D.required]})}}e("DeviceProfileConfigComponent",rt),rt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:rt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class ot extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=W(this.store).tbelEnabled,this.scriptLanguage=d,this.serviceType=p.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[D.required,D.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[D.required,D.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:d.JS,[D.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===d.JS?[D.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===d.TBEL?[D.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(){const e=this.generatorConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",r=this.generatorConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.generatorConfigForm.get(t).setValue(e)}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}var at;e("GeneratorConfigComponent",ot),ot.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ot,deps:[{token:G.Store},{token:E.UntypedFormBuilder},{token:X.NodeScriptTestService},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ot.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ot,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:Y.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:re.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ae.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ot,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder},{type:X.NodeScriptTestService},{type:j.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(at||(at={}));const it=new Map([[at.CUSTOMER,"tb.rulenode.originator-customer"],[at.TENANT,"tb.rulenode.originator-tenant"],[at.RELATED,"tb.rulenode.originator-related"],[at.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[at.ENTITY,"tb.rulenode.originator-entity"]]);var lt;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(lt||(lt={}));const st=new Map([[lt.CIRCLE,"tb.rulenode.perimeter-circle"],[lt.POLYGON,"tb.rulenode.perimeter-polygon"]]);var mt;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(mt||(mt={}));const ut=new Map([[mt.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[mt.SECONDS,"tb.rulenode.time-unit-seconds"],[mt.MINUTES,"tb.rulenode.time-unit-minutes"],[mt.HOURS,"tb.rulenode.time-unit-hours"],[mt.DAYS,"tb.rulenode.time-unit-days"]]);var pt;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(pt||(pt={}));const dt=new Map([[pt.METER,"tb.rulenode.range-unit-meter"],[pt.KILOMETER,"tb.rulenode.range-unit-kilometer"],[pt.FOOT,"tb.rulenode.range-unit-foot"],[pt.MILE,"tb.rulenode.range-unit-mile"],[pt.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var ct;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(ct||(ct={}));const ft=new Map([[ct.ID,"tb.rulenode.entity-details-id"],[ct.TITLE,"tb.rulenode.entity-details-title"],[ct.COUNTRY,"tb.rulenode.entity-details-country"],[ct.STATE,"tb.rulenode.entity-details-state"],[ct.CITY,"tb.rulenode.entity-details-city"],[ct.ZIP,"tb.rulenode.entity-details-zip"],[ct.ADDRESS,"tb.rulenode.entity-details-address"],[ct.ADDRESS2,"tb.rulenode.entity-details-address2"],[ct.PHONE,"tb.rulenode.entity-details-phone"],[ct.EMAIL,"tb.rulenode.entity-details-email"],[ct.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var gt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(gt||(gt={}));const yt=new Map([[gt.FIRST,"tb.rulenode.first"],[gt.LAST,"tb.rulenode.last"],[gt.ALL,"tb.rulenode.all"]]),xt=new Map([[gt.FIRST,"tb.rulenode.first-mode-hint"],[gt.LAST,"tb.rulenode.last-mode-hint"],[gt.ALL,"tb.rulenode.all-mode-hint"]]);var bt,ht;!function(e){e.ASC="ASC",e.DESC="DESC"}(bt||(bt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(ht||(ht={}));const Ct=new Map([[ht.ATTRIBUTES,"tb.rulenode.attributes"],[ht.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[ht.FIELDS,"tb.rulenode.fields"]]),vt=new Map([[ht.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[ht.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[ht.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),Ft=new Map([[bt.ASC,"tb.rulenode.ascending"],[bt.DESC,"tb.rulenode.descending"]]);var Lt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Lt||(Lt={}));const kt=new Map([[Lt.STANDARD,"tb.rulenode.sqs-queue-standard"],[Lt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),Tt=["anonymous","basic","cert.PEM"],It=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Nt=["sas","cert.PEM"],St=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var qt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(qt||(qt={}));const Mt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],At=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Gt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Gt||(Gt={}));const Et=new Map([[Gt.CUSTOM,{value:Gt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Gt.ADD,{value:Gt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Gt.SUB,{value:Gt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Gt.MULT,{value:Gt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Gt.DIV,{value:Gt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Gt.SIN,{value:Gt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Gt.SINH,{value:Gt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Gt.COS,{value:Gt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Gt.COSH,{value:Gt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Gt.TAN,{value:Gt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Gt.TANH,{value:Gt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Gt.ACOS,{value:Gt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Gt.ASIN,{value:Gt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Gt.ATAN,{value:Gt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Gt.ATAN2,{value:Gt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Gt.EXP,{value:Gt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Gt.EXPM1,{value:Gt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Gt.SQRT,{value:Gt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Gt.CBRT,{value:Gt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Gt.GET_EXP,{value:Gt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Gt.HYPOT,{value:Gt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Gt.LOG,{value:Gt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Gt.LOG10,{value:Gt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Gt.LOG1P,{value:Gt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Gt.CEIL,{value:Gt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Gt.FLOOR,{value:Gt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Gt.FLOOR_DIV,{value:Gt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Gt.FLOOR_MOD,{value:Gt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Gt.ABS,{value:Gt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Gt.MIN,{value:Gt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Gt.MAX,{value:Gt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Gt.POW,{value:Gt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Gt.SIGNUM,{value:Gt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Gt.RAD,{value:Gt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Gt.DEG,{value:Gt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Dt,Vt,wt;!function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Dt||(Dt={})),function(e){e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA"}(Vt||(Vt={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(wt||(wt={}));const Pt=new Map([[wt.DATA,"tb.rulenode.message"],[wt.METADATA,"tb.rulenode.metadata"]]),Rt=new Map([[Dt.ATTRIBUTE,"tb.rulenode.attribute-type"],[Dt.TIME_SERIES,"tb.rulenode.time-series-type"],[Dt.CONSTANT,"tb.rulenode.constant-type"],[Dt.MESSAGE_BODY,"tb.rulenode.message-body-type"],[Dt.MESSAGE_METADATA,"tb.rulenode.message-metadata-type"]]),Ot=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var Ht,Kt;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(Ht||(Ht={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(Kt||(Kt={}));const Bt=new Map([[Ht.SHARED_SCOPE,"tb.rulenode.shared-scope"],[Ht.SERVER_SCOPE,"tb.rulenode.server-scope"],[Ht.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class Ut extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=lt,this.perimeterTypes=Object.keys(lt),this.perimeterTypeTranslationMap=st,this.rangeUnits=Object.keys(pt),this.rangeUnitTranslationMap=dt,this.timeUnits=Object.keys(mt),this.timeUnitsTranslationMap=ut}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[D.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[D.required]],perimeterType:[e?e.perimeterType:null,[D.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[D.required,D.min(1),D.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[D.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[D.required,D.min(1),D.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[D.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([D.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==lt.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([D.required,D.min(-90),D.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([D.required,D.min(-180),D.max(180)]),this.geoActionConfigForm.get("range").setValidators([D.required,D.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([D.required])),t||n!==lt.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([D.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",Ut),Ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ut,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ut,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ut,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class zt extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=W(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[D.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===d.JS?[D.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===d.TBEL?[D.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.logConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",r=this.logConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.logConfigForm.get(t).setValue(e)}))}onValidate(){this.logConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",zt),zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zt,deps:[{token:G.Store},{token:E.UntypedFormBuilder},{token:X.NodeScriptTestService},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:zt,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:re.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ae.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zt,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder},{type:X.NodeScriptTestService},{type:j.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class _t extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[D.required,D.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[D.required]]})}}e("MsgCountConfigComponent",_t),_t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_t,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:_t,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_t,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[D.required,D.min(1),D.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([D.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([D.required,D.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",jt),jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:jt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:jt,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:jt,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n \n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class $t extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[D.required]]})}}e("PushToCloudConfigComponent",$t),$t.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$t,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$t.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:$t,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$t,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Qt extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[D.required]]})}}e("PushToEdgeConfigComponent",Qt),Qt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Qt,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qt,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Jt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",Jt),Jt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Jt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Jt,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Jt,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Yt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[D.required,D.min(0)]]})}}e("RpcRequestConfigComponent",Yt),Yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Yt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Yt,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Yt,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Wt extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ce(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(V),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[D.required]],value:[e[n],[D.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[D.required]],value:["",[D.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Wt),Wt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Wt,deps:[{token:G.Store},{token:j.TranslateService},{token:t.Injector},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Wt,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:w,useExisting:a((()=>Wt)),multi:!0},{provide:P,useExisting:a((()=>Wt)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:fe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ye.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Wt,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:w,useExisting:a((()=>Wt)),multi:!0},{provide:P,useExisting:a((()=>Wt)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:t.Injector},{type:E.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class Xt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[D.required,D.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[D.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",Xt),Xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Xt,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Wt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xt,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Zt extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[D.required,D.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Zt),Zt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zt,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Zt,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zt,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class en extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[D.required,D.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[D.required,D.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",en),en.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:en,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),en.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:en,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:en,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class tn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=m,this.attributeScopes=Object.keys(m),this.telemetryTypeTranslationsMap=u,this.separatorKeysCodes=[ie,le,se]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[D.required]],keys:[e?e.keys:null,[D.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==m.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",tn),tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:tn,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tn,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class nn extends b{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=Et,this.ArgumentType=Dt,this.attributeScopeMap=Bt,this.argumentTypeResultMap=Rt,this.arguments=Object.values(Dt),this.attributeScope=Object.values(Ht),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.ngControl=this.injector.get(V),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray(),n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormGroup.get("arguments").controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormGroup.get("arguments").removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormGroup.get("arguments"),n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Gt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([D.minLength(this.minArgs),D.maxLength(this.maxArgs)]),this.argumentsFormGroup.get("arguments").value.length>this.maxArgs&&(this.argumentsFormGroup.get("arguments").controls.length=this.maxArgs);this.argumentsFormGroup.get("arguments").value.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Dt.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==Dt.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormGroup.get("arguments").controls.forEach(((e,t)=>{e.get("name").setValue(Ot[t])}))}updateModel(){const e=this.argumentsFormGroup.get("arguments").value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",nn),nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nn,deps:[{token:G.Store},{token:j.TranslateService},{token:t.Injector},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:nn,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:w,useExisting:a((()=>nn)),multi:!0},{provide:P,useExisting:a((()=>nn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n help\n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:xe.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:xe.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:be.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:be.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:be.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ye.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nn,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:w,useExisting:a((()=>nn)),multi:!0},{provide:P,useExisting:a((()=>nn)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n
\n \n tb.rulenode.argument-type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.argument-type-field-input-required\n \n \n \n tb.rulenode.argument-key-field-input\n \n help\n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n
\n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:t.Injector},{type:E.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class rn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ce(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...Et.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(he((e=>{let t;t="string"==typeof e&&Gt[e]?Gt[e]:null,this.updateView(t)})),Ce((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=Et.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",rn),rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rn,deps:[{token:G.Store},{token:j.TranslateService},{token:t.Injector},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:rn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:w,useExisting:a((()=>rn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Te.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Ie.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:w,useExisting:a((()=>rn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:t.Injector},{type:E.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class on extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Gt,this.ArgumentTypeResult=Vt,this.argumentTypeResultMap=Rt,this.attributeScopeMap=Bt,this.argumentsResult=Object.values(Vt),this.attributeScopeResult=Object.values(Kt)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[D.required]],arguments:[e?e.arguments:null,[D.required]],customFunction:[e?e.customFunction:"",[D.required]],result:this.fb.group({type:[e?e.result.type:null,[D.required]],attributeScope:[e?e.result.attributeScope:null,[D.required]],key:[e?e.result.key:"",[D.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Gt.CUSTOM?this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Vt.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",on),on.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:on,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),on.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:on,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:E.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:nn,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:rn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:on,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n \n \n
\n
\n tb.rulenode.result-title\n
\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(argument) | translate }}\n \n \n \n tb.rulenode.type-field-input-required\n \n \n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n
\n \n {{\'tb.rulenode.add-to-body-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class an{constructor(e,t){this.store=e,this.fb=t,this.subscriptSizing="fixed",this.searchText="",this.dirty=!1,this.messageTypes=["POST_ATTRIBUTES_REQUEST","POST_TELEMETRY_REQUEST"],this.propagateChange=e=>{},this.messageTypeFormGroup=this.fb.group({messageType:[null,[D.required,D.maxLength(255)]]})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.outputMessageTypes=this.messageTypeFormGroup.get("messageType").valueChanges.pipe(he((e=>{this.updateView(e)})),Ce((e=>e||"")),ve((e=>this.fetchMessageTypes(e))))}writeValue(e){this.searchText="",this.modelValue=e,this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1}),this.dirty=!0}onFocus(){this.dirty&&(this.messageTypeFormGroup.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0}),this.dirty=!1)}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}displayMessageTypeFn(e){return e||void 0}fetchMessageTypes(e,t=!1){return this.searchText=e,Ne(this.messageTypes).pipe(Ce((n=>n.filter((n=>t?!!e&&n===e:!e||n.toUpperCase().startsWith(e.toUpperCase()))))))}clear(){this.messageTypeFormGroup.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}}e("OutputMessageTypeAutocompleteComponent",an),an.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:an,deps:[{token:G.Store},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),an.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:an,selector:"tb-output-message-type-autocomplete",inputs:{autocompleteHint:"autocompleteHint",subscriptSizing:"subscriptSizing"},providers:[{provide:w,useExisting:a((()=>an)),multi:!0}],viewQueries:[{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0,static:!0}],ngImport:t,template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Te.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:an,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:w,useExisting:a((()=>an)),multi:!0}],template:'\n \n \n \n \n {{msgType}}\n \n \n {{autocompleteHint | translate}}\n \n {{ \'tb.rulenode.output-message-type-required\' | translate }}\n \n \n {{ \'tb.rulenode.output-message-type-max-length\' | translate }}\n \n\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder}]},propDecorators:{messageTypeInput:[{type:o,args:["messageTypeInput",{static:!0}]}],autocompleteHint:[{type:i}],subscriptSizing:[{type:i}]}});class ln extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.destroy$=new Se,this.serviceType=p.TB_RULE_ENGINE,this.deduplicationStrategie=gt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=yt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[Z(e?.interval)?e.interval:null,[D.required,D.min(1)]],strategy:[Z(e?.strategy)?e.strategy:null,[D.required]],outMsgType:[Z(e?.outMsgType)?e.outMsgType:null,[D.required]],queueName:[Z(e?.queueName)?e.queueName:null,[D.required]],maxPendingMsgs:[Z(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[D.required,D.min(1),D.max(1e3)]],maxRetries:[Z(e?.maxRetries)?e.maxRetries:null,[D.required,D.min(0),D.max(100)]]}),this.deduplicationConfigForm.get("strategy").valueChanges.pipe(Fe(this.destroy$)).subscribe((e=>{this.enableControl(e)}))}updateValidators(e){this.enableControl(this.deduplicationConfigForm.get("strategy").value)}validatorTriggers(){return["strategy"]}enableControl(e){e===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("DeduplicationConfigComponent",ln),ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ln,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ln,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Y.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:qe.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:qe.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:qe.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:qe.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:an,selector:"tb-output-message-type-autocomplete",inputs:["autocompleteHint","subscriptSizing"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ln,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:"
\n \n {{'tb.rulenode.interval' | translate}}\n \n {{'tb.rulenode.interval-hint' | translate}}\n \n {{'tb.rulenode.interval-required' | translate}}\n \n \n {{'tb.rulenode.interval-min-error' | translate}}\n \n \n \n {{'tb.rulenode.strategy' | translate}}\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n {{'tb.rulenode.strategy-first-hint' | translate}}\n {{'tb.rulenode.strategy-last-hint' | translate}}\n \n {{'tb.rulenode.strategy-required' | translate}}\n \n \n
\n \n \n \n \n
\n \n \n \n
\n
Advanced settings
\n
\n
\n
\n \n \n {{'tb.rulenode.max-pending-msgs' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-hint' | translate}}\n \n {{'tb.rulenode.max-pending-msgs-required' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-max-error' | translate}}\n \n \n {{'tb.rulenode.max-pending-msgs-min-error' | translate}}\n \n \n \n {{'tb.rulenode.max-retries' | translate}}\n \n {{'tb.rulenode.max-retries-hint' | translate}}\n \n {{'tb.rulenode.max-retries-required' | translate}}\n \n \n {{'tb.rulenode.max-retries-max-error' | translate}}\n \n \n {{'tb.rulenode.max-retries-min-error' | translate}}\n \n \n \n
\n
\n",styles:[":host ::ng-deep .mat-expansion-panel.advanced-settings{border:none;box-shadow:none;padding:0}:host ::ng-deep .mat-expansion-panel.advanced-settings .mat-expansion-panel-body{padding:0}:host ::ng-deep .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:not([aria-disabled=true]):hover{background:white}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class sn extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(V),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[e[n],[D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",sn),sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:sn,deps:[{token:G.Store},{token:j.TranslateService},{token:t.Injector},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:sn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:w,useExisting:a((()=>sn)),multi:!0},{provide:P,useExisting:a((()=>sn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n
\n
\n \n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ge.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:fe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ye.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),Ae([h()],sn.prototype,"disabled",void 0),Ae([h()],sn.prototype,"uniqueKeyValuePairValidator",void 0),Ae([h()],sn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:sn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:w,useExisting:a((()=>sn)),multi:!0},{provide:P,useExisting:a((()=>sn)),multi:!0}],template:'
\n
\n \n
\n
\n
\n
\n \n {{ keyText }}\n \n \n {{ keyRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n
\n
\n \n \n \n
\n \n
\n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-kv-map-config{margin-bottom:12px}:host ::ng-deep .tb-kv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-kv-map-config .body{margin-top:7px;max-height:363px;overflow:auto}:host ::ng-deep .tb-kv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-kv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-kv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:t.Injector},{type:E.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class mn{constructor(e,t){this.store=e,this.fb=t,this.destroy$=new Se}ngOnInit(){this.slideToggleControlGroup=this.fb.group({slideToggleControl:[null,[]]}),this.slideToggleControlGroup.get("slideToggleControl").valueChanges.pipe(Fe(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.slideToggleControlGroup.get("slideToggleControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.slideToggleControlGroup.disable({emitEvent:!1}):this.slideToggleControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SlideToggleComponent",mn),mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:mn,deps:[{token:G.Store},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:mn,selector:"tb-slide-toggle",inputs:{slideToggleName:"slideToggleName",slideToggleTooltip:"slideToggleTooltip"},providers:[{provide:w,useExisting:a((()=>mn)),multi:!0}],ngImport:t,template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"],dependencies:[{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ve.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:mn,decorators:[{type:n,args:[{selector:"tb-slide-toggle",providers:[{provide:w,useExisting:a((()=>mn)),multi:!0}],template:'
\n \n {{ slideToggleName }}\n \n info\n
\n',styles:[":host ::ng-deep .slide-toggle-container{align-items:center}:host ::ng-deep .slide-toggle-container .slide-toggle{margin-right:8px}:host ::ng-deep .slide-toggle-container .slide-toggle label{padding-left:12px}:host ::ng-deep .slide-toggle-container .tooltip-icon{width:18px;height:18px;line-height:18px;font-size:18px;color:#e0e0e0}:host ::ng-deep .slide-toggle-container .tooltip-icon:hover{color:#9e9e9e}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder}]},propDecorators:{slideToggleName:[{type:i}],slideToggleTooltip:[{type:i}]}});class un extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ce(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.entityType=x,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[D.required]],maxLevel:[null,[D.min(1)]],relationType:[null],deviceTypes:[null,[D.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:un,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:un,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:w,useExisting:a((()=>un)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ee.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["label","required","disabled","entityType"]},{kind:"component",type:De.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","floatLabel","required","disabled","subscriptSizing"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:mn,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:w,useExisting:a((()=>un)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n',styles:[":host .relation-level{margin-bottom:16px}:host .last-level-slide-toggle{margin:8px 0 24px}:host .relation-type-autocomplete{margin-bottom:16px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class pn{constructor(){this.required=!1}}e("FieldsetComponent",pn),pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pn,deps:[],target:t.ɵɵFactoryTarget.Component}),pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:pn,selector:"tb-fieldset-component",inputs:{label:"label",required:"required"},ngImport:t,template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]}]}),Ae([h()],pn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pn,decorators:[{type:n,args:[{selector:"tb-fieldset-component",template:'
\n {{ label }}{{ required ? \'*\' : \'\' }}\n
\n \n
\n
\n',styles:[".fields-group{padding:0 16px;margin:0;border:1px solid #E0E0E0;border-radius:4px}.fields-group .fieldset-content{align-items:center}.fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}.fields-group legend{color:#757575;width:-moz-fit-content;width:fit-content;margin-bottom:4px}.fields-group legend+*{display:block}.fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],propDecorators:{label:[{type:i}],required:[{type:i}]}});class dn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ce(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[D.required]],maxLevel:[null,[D.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:dn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:dn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:w,useExisting:a((()=>dn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:we.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"component",type:mn,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:pn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:w,useExisting:a((()=>dn)),multi:!0}],template:'
\n \n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n \n \n
\n \n
\n
\n
\n',styles:[":host .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host .last-level-slide-toggle{margin-bottom:18px;display:inline-block}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class cn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ce(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.message-type",this.separatorKeysCodes=[ie,le,se],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(C))this.messageTypesList.push({name:v.get(C[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Le(""),Ce((e=>e||"")),ve((e=>this.fetchMessageTypes(e))),ke())}ngAfterViewInit(){}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return!!(e&&null!=e&&e.length>0)}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ne(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ne(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t=null;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:cn,deps:[{token:G.Store},{token:j.TranslateService},{token:F.TruncatePipe},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:cn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:w,useExisting:a((()=>cn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n { messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Te.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Te.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Ie.HighlightPipe,name:"highlight"},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:w,useExisting:a((()=>cn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n { messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n \n {{ \'tb.rulenode.message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:F.TruncatePipe},{type:E.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class fn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ce(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=Tt,this.credentialsTypeTranslationsMap=It,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[D.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){Z(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([D.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[D.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(D.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:fn,deps:[{token:G.Store},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:fn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:w,useExisting:a((()=>fn)),multi:!0},{provide:P,useExisting:a((()=>fn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:qe.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:qe.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:qe.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:qe.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:qe.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Pe.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Re.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:w,useExisting:a((()=>fn)),multi:!0},{provide:P,useExisting:a((()=>fn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});class gn{constructor(e,t,n){this.store=e,this.fb=t,this.translate=n,this.destroy$=new Se,this.selectOptions=[];for(const e of Pt.keys())this.selectOptions.push({value:e,name:this.translate.instant(Pt.get(e))})}ngOnInit(){this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(Fe(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("MsgMetadataChipComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:gn,deps:[{token:G.Store},{token:E.FormBuilder},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:gn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText"},providers:[{provide:w,useExisting:a((()=>gn)),multi:!0}],ngImport:t,template:'
\n \n \n {{ option.name }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:ue.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ue.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:w,useExisting:a((()=>gn)),multi:!0}],template:'
\n \n \n {{ option.name }}\n \n
\n',styles:[":host{width:100%}:host .chip-label{font-weight:400;font-size:12px;letter-spacing:.25px;color:#3d3d3d}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder},{type:j.TranslateService}]},propDecorators:{labelText:[{type:i}]}});class yn extends b{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new Se,this.sourceFieldSubcritption=[],this.propagateChange=null,this.valueChangeSubscription=null,this.disabled=!1,this.required=!1}ngOnInit(){this.ngControl=this.injector.get(V),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({}),this.svListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[D.required]],value:[e[n],[D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}));this.svListFormGroup.setControl("keyVals",this.fb.array(t));for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e);this.valueChangeSubscription=this.svListFormGroup.valueChanges.pipe(Fe(this.destroy$)).subscribe((e=>{this.updateModel()}))}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)Z(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.svListFormGroup.get("keyVals").removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){const e=this.svListFormGroup.get("keyVals");e.push(this.fb.group({key:["",[D.required]],value:["",[D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(e.controls[e.length-1])}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(Fe(this.destroy$)).subscribe((t=>{e.get("value").patchValue(this.targetKeyPrefix+t[0].toUpperCase()+t.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:yn,deps:[{token:G.Store},{token:j.TranslateService},{token:t.Injector},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:yn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:w,useExisting:a((()=>yn)),multi:!0},{provide:P,useExisting:a((()=>yn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n
\n
\n
\n
\n \n {{ selectText }}\n \n \n {{option.name}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n {{ hintText }}\n \n
\n
\n \n \n
\n \n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ge.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:fe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:ye.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),Ae([h()],yn.prototype,"disabled",void 0),Ae([h()],yn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:w,useExisting:a((()=>yn)),multi:!0},{provide:P,useExisting:a((()=>yn)),multi:!0}],template:'
\n
\n \n
\n
\n
\n
\n \n {{ selectText }}\n \n \n {{option.name}}\n \n \n \n {{ selectRequiredText }}\n \n \n arrow_forward\n \n {{ valText }}\n \n \n {{ valRequiredText }}\n \n \n
\n \n
\n
\n
\n {{ hintText }}\n \n
\n
\n \n \n
\n \n
\n',styles:[":host ::ng-deep{width:100%}:host ::ng-deep .tb-sv-map-config{margin-bottom:12px}:host ::ng-deep .tb-sv-map-config .map-label{font-weight:400;font-size:12px;color:#3d3d3d;letter-spacing:.25px}:host ::ng-deep .tb-sv-map-config .body{max-height:363px;overflow:auto;margin-top:7px}:host ::ng-deep .tb-sv-map-config .body .mapping-block{margin-bottom:15px}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block{border:1px solid #E0E0E0;width:100%;border-radius:6px;padding:22px 22px 0;align-items:center}:host ::ng-deep .tb-sv-map-config .body .mapping-block .inputs-block .arrow-icon{width:24px;height:24px;line-height:24px;font-size:24px;margin:0 2px 22px;color:#9e9e9e}:host ::ng-deep .tb-sv-map-config tb-error{display:block;margin-top:-12px;margin-bottom:8px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:t.Injector},{type:E.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class xn extends b{get required(){return this.requiredValue}set required(e){this.requiredValue=ce(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(g),this.directionTypeTranslations=y,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[D.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:xn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:xn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:w,useExisting:a((()=>xn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:we.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:w,useExisting:a((()=>xn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class bn{constructor(e,t,n){this.store=e,this.translate=t,this.fb=n,this.destroy$=new Se,this.separatorKeysCodes=[ie,le,se]}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[null,[]],sharedAttributeNames:[null,[]],serverAttributeNames:[null,[]],latestTsKeyNames:[null,[]],getLatestValueWithTs:[!1,[]]}),this.attributeControlGroup.valueChanges.pipe(Fe(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}writeValue(e){this.attributeControlGroup.patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}removeKey(e,t){const n=this.attributeControlGroup.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.attributeControlGroup.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.attributeControlGroup.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.attributeControlGroup.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}clearChipGrid(e){this.attributeControlGroup.get(e).patchValue([],{emitEvent:!0})}}e("SelectAttributesComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:bn,deps:[{token:G.Store},{token:j.TranslateService},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:bn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:w,useExisting:a((()=>bn)),multi:!0}],ngImport:t,template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin-bottom:22px;display:block}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ge.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:mn,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:w,useExisting:a((()=>bn)),multi:!0}],template:'
\n \n tb.rulenode.client-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.shared-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.server-attributes\n \n \n {{key}}\n close\n \n \n \n \n \n \n tb.rulenode.latest-telemetry\n \n \n {{key}}\n close\n \n \n \n \n \n
\n {{ \'tb.rulenode.kv-map-pattern-hint\' | translate }}\n \n
\n \n \n
\n',styles:[":host ::ng-deep .chip-grid{width:100%;margin-bottom:16px}:host ::ng-deep .fetch-slide-toggle{width:100%;margin-bottom:22px;display:block}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:E.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class hn{}e("RulenodeCoreConfigCommonModule",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:hn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),hn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:hn,declarations:[sn,un,dn,cn,fn,Je,nn,rn,an,Wt,gn,mn,yn,pn,xn,bn],imports:[K,L,Me],exports:[sn,un,dn,cn,fn,Je,nn,rn,an,Wt,gn,mn,yn,pn,xn,bn]}),hn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:hn,imports:[K,L,Me]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:hn,decorators:[{type:l,args:[{declarations:[sn,un,dn,cn,fn,Je,nn,rn,an,Wt,gn,mn,yn,pn,xn,bn],imports:[K,L,Me],exports:[sn,un,dn,cn,fn,Je,nn,rn,an,Wt,gn,mn,yn,pn,xn,bn]}]}]});class Cn{}e("RuleNodeCoreConfigActionModule",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Cn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Cn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Cn,declarations:[tn,We,Zt,Yt,zt,Ye,Ze,et,tt,jt,nt,ot,Ut,_t,Jt,Xt,en,Xe,rt,Qt,$t,on,ln],imports:[K,L,Me,hn],exports:[tn,We,Zt,Yt,zt,Ye,Ze,et,tt,jt,nt,ot,Ut,_t,Jt,Xt,en,Xe,rt,Qt,$t,on,ln]}),Cn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Cn,imports:[K,L,Me,hn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Cn,decorators:[{type:l,args:[{declarations:[tn,We,Zt,Yt,zt,Ye,Ze,et,tt,jt,nt,ot,Ut,_t,Jt,Xt,en,Xe,rt,Qt,$t,on,ln],imports:[K,L,Me,hn],exports:[tn,We,Zt,Yt,zt,Ye,Ze,et,tt,jt,nt,ot,Ut,_t,Jt,Xt,en,Xe,rt,Qt,$t,on,ln]}]}]});class vn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ie,le,se]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[D.min(0),D.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:Z(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:Z(e?.outputValueKey)?e.outputValueKey:null,useCache:!Z(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!Z(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:Z(e?.periodValueKey)?e.periodValueKey:null,round:Z(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!Z(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return ee(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([D.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:vn,deps:[{token:G.Store},{token:j.TranslateService},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:vn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:mn,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n \n \n \n \n \n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n",styles:[":host ::ng-deep .slide-toggles-block .slide-toggle{margin:12px 0}:host ::ng-deep .period-input{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:E.FormBuilder}]}});class Fn extends s{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=ht;for(const e of Ct.keys())e!==ht.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Ct.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,ee(e)}toggleChange(e){this.customerAttributesConfigForm.get("dataToFetch").patchValue(e,{emitEvent:!0})}prepareInputConfig(e){let t,n;return t=Z(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:Z(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=Z(e?.attrMapping)?e.attrMapping:Z(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:Z(e?.fetchTo)?e.fetchTo:wt.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[D.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Fn,deps:[{token:G.Store},{token:E.FormBuilder},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Fn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{margin-bottom:12px;width:420px}\n"],dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Oe.ToggleHeaderComponent,selector:"tb-toggle-header",inputs:["value","options","name","useSelectOnMdLg","ignoreMdLgSize","appearance"],outputs:["valueChange"]},{kind:"component",type:sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:gn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:pn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{margin-bottom:12px;width:420px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder},{type:j.TranslateService}]}});class Ln extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[D.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return te(e)&&(e.attributesControl={clientAttributeNames:Z(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:Z(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:Z(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:Z(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!Z(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:Z(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!Z(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:Z(e?.fetchTo)?e.fetchTo:wt.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ln,deps:[{token:G.Store},{token:j.TranslateService},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Ln,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"],dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:un,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:gn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:mn,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:pn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:bn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .device-relations{width:100%}:host .failure-toggle{margin:25px 0}:host .device-attribute{margin-top:12px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:E.FormBuilder}]}});class kn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.entityDetailsTranslationsMap=ft,this.entityDetailsList=[],this.searchText="",this.displayDetailsFn=this.displayDetails.bind(this);for(const e of Object.keys(ct))this.entityDetailsList.push(ct[e]);this.detailsFormControl=new R(""),this.filteredEntityDetails=this.detailsFormControl.valueChanges.pipe(Le(""),Ce((e=>e||"")),ve((e=>this.fetchEntityDetails(e))),ke())}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return this.searchText="",this.detailsFormControl.patchValue("",{emitEvent:!0}),this.detailsList=e?e.detailsList:[],t=Z(e?.addToMetadata)?e.addToMetadata?wt.METADATA:wt.DATA:e?.fetchTo?e.fetchTo:wt.DATA,{detailsList:Z(e?.detailsList)?e.detailsList:null,fetchTo:t}}prepareOutputConfig(e){return e.detailsList=this.detailsList,e}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[D.required]],fetchTo:[e.fetchTo,[]]}),this.detailsList=e?e.detailsList:[]}displayDetails(e){return e?this.translate.instant(ft.get(e)):void 0}fetchEntityDetails(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ne(this.entityDetailsList.filter((t=>this.translate.instant(ft.get(ct[t])).toUpperCase().includes(e))))}return Ne(this.entityDetailsList)}detailsFieldSelected(e){this.addDetailsField(e.option.value),this.clear("")}removeDetailsField(e){const t=this.detailsList.indexOf(e);t>=0&&(this.detailsList.splice(t,1),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}addDetailsField(e){this.detailsList||(this.detailsList=[]);-1===this.detailsList.indexOf(e)&&(this.detailsList.push(e),this.entityDetailsConfigForm.get("detailsList").setValue(this.detailsList))}onEntityDetailsInputFocus(){this.detailsFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clearChipGrid(){this.detailsList=[],this.entityDetailsConfigForm.get("detailsList").patchValue([],{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}clear(e=""){this.detailsInput.nativeElement.value=e,this.detailsFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.detailsInput.nativeElement.blur(),this.detailsInput.nativeElement.focus()}),0)}}e("EntityDetailsConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:kn,deps:[{token:G.Store},{token:j.TranslateService},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:kn,selector:"tb-enrichment-node-entity-details-config",viewQueries:[{propertyName:"detailsInput",first:!0,predicate:["detailsInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Te.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Te.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Te.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:gn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Ie.HighlightPipe,name:"highlight"},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n {{ \'tb.rulenode.entity-details\' | translate }}\n \n \n \n {{entityDetailsTranslationsMap.get(details) | translate}}\n \n close\n \n \n \n \n \n \n \n \n \n
\n
\n {{ \'tb.rulenode.no-entity-details-matching\' | translate }}\n
\n
\n
\n
\n {{ \'tb.rulenode.entity-details-list-empty\' | translate }}\n
\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:E.FormBuilder}]},propDecorators:{detailsInput:[{type:o,args:["detailsInput",{static:!1}]}]}});class Tn extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ie,le,se],this.aggregationTypes=k,this.aggregations=Object.keys(k),this.aggregationTypesTranslations=T,this.fetchMode=gt,this.samplingOrders=Object.keys(bt),this.samplingOrdersTranslate=Ft,this.timeUnits=Object.values(mt),this.timeUnitsTranslationMap=ut,this.deduplicationStrategiesHintTranslations=xt,this.headerOptions=[],this.timeUnitMap={[mt.MILLISECONDS]:1,[mt.SECONDS]:1e3,[mt.MINUTES]:6e4,[mt.HOURS]:36e5,[mt.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of yt.keys())this.headerOptions.push({value:e,name:this.translate.instant(yt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[]],aggregation:[e.aggregation,[D.required]],fetchMode:[e.fetchMode,[D.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,ee(e)}prepareInputConfig(e){return te(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:Z(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:Z(e?.aggregation)?e.aggregation:k.NONE,fetchMode:Z(e?.fetchMode)?e.fetchMode:gt.FIRST,orderBy:Z(e?.orderBy)?e.orderBy:bt.ASC,limit:Z(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!Z(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:Z(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:Z(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:mt.MINUTES,endInterval:Z(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:Z(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:mt.MINUTES},startIntervalPattern:Z(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:Z(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===gt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([D.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([D.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([D.required,D.min(2),D.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([D.required,D.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([D.required,D.min(1),D.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([D.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([D.required,D.min(1),D.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([D.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}}e("GetTelemetryFromDatabaseConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Tn,deps:[{token:G.Store},{token:j.TranslateService},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Tn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n \n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px;align-items:center;width:100%}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px;width:630px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .input-block{width:100%}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .input-block .additional-inputs{margin-bottom:16px}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ge.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style"]},{kind:"component",type:oe.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:E.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Oe.ToggleHeaderComponent,selector:"tb-toggle-header",inputs:["value","options","name","useSelectOnMdLg","ignoreMdLgSize","appearance"],outputs:["valueChange"]},{kind:"component",type:mn,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:pn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n {{\'tb.rulenode.timeseries-keys\' | translate}}\n \n \n {{key}}\n close\n \n \n \n \n \n {{ "tb.rulenode.general-pattern-hint" | translate }}\n \n \n \n \n\n \n \n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()} }}\n
\n
\n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n
\n {{ \'tb.rulenode.metadata-dynamic-interval-hint\' | translate }}\n \n
\n
\n
\n
\n \n
\n \n \n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n
\n',styles:[":host ::ng-deep label.tb-title{margin-bottom:-10px}:host ::ng-deep .fetch-interval{margin-top:12px}:host ::ng-deep .fetch-interval .interval-slide-toggle{width:100%;margin:4px 0 16px}:host ::ng-deep .fetch-interval .input-block{width:100%}:host ::ng-deep .interval-description{text-align:center;font-size:12px;color:#3d3d3d;margin-bottom:9px;font-weight:500}:host ::ng-deep .fetch-strategy-fieldset{margin-top:12px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block{margin-top:8px;align-items:center;width:100%}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .fetch-mod-toggle{margin-bottom:12px;width:630px}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .input-block{width:100%}:host ::ng-deep .fetch-strategy-fieldset .fetch-strategy-block .input-block .additional-inputs{margin-bottom:16px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:E.FormBuilder}]}});class In extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return te(e)&&(e.attributesControl={clientAttributeNames:Z(e?.clientAttributeNames)?e.clientAttributeNames:null,latestTsKeyNames:Z(e?.latestTsKeyNames)?e.latestTsKeyNames:null,serverAttributeNames:Z(e?.serverAttributeNames)?e.serverAttributeNames:null,sharedAttributeNames:Z(e?.sharedAttributeNames)?e.sharedAttributeNames:null,getLatestValueWithTs:!!Z(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:Z(e?.fetchTo)?e.fetchTo:wt.METADATA,tellFailureIfAbsent:!!Z(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:Z(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:In,deps:[{token:G.Store},{token:j.TranslateService},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:In,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"],dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:gn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:mn,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:pn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"component",type:bn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n \n \n \n \n \n \n
\n',styles:[":host label.tb-title{margin-bottom:-10px}:host .failure-slide-toggle{margin:25px 0}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:E.FormBuilder}]}});class Nn extends s{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of Object.keys(I))this.originatorFields.push({value:I[e].value,name:this.translate.instant(I[e].name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return ee(e)}prepareInputConfig(e){return{dataMapping:Z(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:Z(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:Z(e?.fetchTo)?e.fetchTo:wt.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[D.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Nn,deps:[{token:G.Store},{token:E.FormBuilder},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Nn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"],dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:gn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:mn,selector:"tb-slide-toggle",inputs:["slideToggleName","slideToggleTooltip"]},{kind:"component",type:yn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:pn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .msg-metadata-chip{margin-bottom:12px}:host .skip-slide-toggle{margin-top:20px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder},{type:j.TranslateService}]}});class Sn extends s{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=ht,this.msgMetadataLabelTranslations=vt,this.originatorFields=[],this.fetchToData=[],this.destroy$=new Se,this.defaultKvMap={serialNumber:"sn"},this.defaultSvMap={[I.name.value]:`relatedEntity${this.translate.instant(I.name.name)}`},this.dataToFetchPrevValue="";for(const e of Object.keys(I))this.originatorFields.push({value:I[e].value,name:this.translate.instant(I[e].name)});for(const e of Ct.keys())this.fetchToData.push({value:e,name:this.translate.instant(Ct.get(e))})}toggleChange(e){this.relatedAttributesConfigForm.get("dataToFetch").patchValue(e,{emitEvent:!0})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,ee(e)}prepareInputConfig(e){let t;return Z(e?.telemetry)?this.dataToFetchPrevValue=e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:this.dataToFetchPrevValue=Z(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,t=Z(e?.attrMapping)?e.attrMapping:Z(e?.dataMapping)?e.dataMapping:null,{relationsQuery:Z(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:this.dataToFetchPrevValue,dataMapping:t,fetchTo:Z(e?.fetchTo)?e.fetchTo:wt.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[D.required]],dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[D.required]],fetchTo:[e.fetchTo,[]]}),this.relatedAttributesConfigForm.get("dataToFetch").valueChanges.pipe(Fe(this.destroy$)).subscribe((e=>{e===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultSvMap,{emitEvent:!1}),e!==ht.FIELDS&&this.dataToFetchPrevValue===ht.FIELDS&&this.relatedAttributesConfigForm.get("dataMapping").patchValue(this.defaultKvMap,{emitEvent:!1}),this.dataToFetchPrevValue=e}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}}e("RelatedAttributesConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Sn,deps:[{token:G.Store},{token:E.FormBuilder},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Sn,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host .fetch-data-block{margin-top:12px}:host .fetch-data-block .fetch-to-data-toggle{margin-bottom:12px;width:630px}:host .fetch-data-block .msg-metadata-chip{margin-bottom:12px}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Oe.ToggleHeaderComponent,selector:"tb-toggle-header",inputs:["value","options","name","useSelectOnMdLg","ignoreMdLgSize","appearance"],outputs:["valueChange"]},{kind:"component",type:sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:dn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:gn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:yn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:pn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n',styles:[":host .fetch-data-block{margin-top:12px}:host .fetch-data-block .fetch-to-data-toggle{margin-bottom:12px;width:630px}:host .fetch-data-block .msg-metadata-chip{margin-bottom:12px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder},{type:j.TranslateService}]}});class qn extends s{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=ht;for(const e of Ct.keys())e!==ht.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Ct.get(e))})}configForm(){return this.tenantAttributesConfigForm}toggleChange(e){this.tenantAttributesConfigForm.get("dataToFetch").patchValue(e,{emitEvent:!0})}prepareInputConfig(e){let t,n;return t=Z(e?.telemetry)?e.telemetry?ht.LATEST_TELEMETRY:ht.ATTRIBUTES:Z(e?.dataToFetch)?e.dataToFetch:ht.ATTRIBUTES,n=Z(e?.attrMapping)?e.attrMapping:Z(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:Z(e?.fetchTo)?e.fetchTo:wt.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===ht.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[D.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:qn,deps:[{token:G.Store},{token:E.FormBuilder},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:qn,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{margin-bottom:12px;width:420px}:host .msg-metadata-chip{margin-bottom:12px}\n"],dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Oe.ToggleHeaderComponent,selector:"tb-toggle-header",inputs:["value","options","name","useSelectOnMdLg","ignoreMdLgSize","appearance"],outputs:["valueChange"]},{kind:"component",type:sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:gn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"component",type:pn,selector:"tb-fieldset-component",inputs:["label","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n \n \n \n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{margin-bottom:12px;width:420px}:host .msg-metadata-chip{margin-bottom:12px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder},{type:j.TranslateService}]}});class Mn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:Z(e?.fetchTo)?e.fetchTo:wt.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mn,deps:[{token:G.Store},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Mn,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:gn,selector:"tb-msg-metadata-chip",inputs:["labelText"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder}]}});class An{}e("RulenodeCoreConfigEnrichmentModule",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:An,deps:[],target:t.ɵɵFactoryTarget.NgModule}),An.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:An,declarations:[Fn,kn,Ln,In,Nn,Tn,Sn,qn,vn,Mn],imports:[K,L,hn],exports:[Fn,kn,Ln,In,Nn,Tn,Sn,qn,vn,Mn]}),An.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:An,imports:[K,L,hn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:An,decorators:[{type:l,args:[{declarations:[Fn,kn,Ln,In,Nn,Tn,Sn,qn,vn,Mn],imports:[K,L,hn],exports:[Fn,kn,Ln,In,Nn,Tn,Sn,qn,vn,Mn]}]}]});class Gn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Nt,this.azureIotHubCredentialsTypeTranslationsMap=St}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[D.required]],host:[e?e.host:null,[D.required]],port:[e?e.port:null,[D.required,D.min(1),D.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[D.required,D.min(1),D.max(200)]],clientId:[e?e.clientId:null,[D.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[D.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([D.required]);break;case"cert.PEM":t.get("privateKey").setValidators([D.required]),t.get("privateKeyFileName").setValidators([D.required]),t.get("cert").setValidators([D.required]),t.get("certFileName").setValidators([D.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Gn,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:qe.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:qe.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:qe.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:qe.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:E.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Pe.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Re.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n \n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class En extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Mt,this.ToByteStandartCharsetTypeTranslationMap=At}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[D.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[D.required]],retries:[e?e.retries:null,[D.min(0)]],batchSize:[e?e.batchSize:null,[D.min(0)]],linger:[e?e.linger:null,[D.min(0)]],bufferMemory:[e?e.bufferMemory:null,[D.min(0)]],acks:[e?e.acks:null,[D.required]],keySerializer:[e?e.keySerializer:null,[D.required]],valueSerializer:[e?e.valueSerializer:null,[D.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([D.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:En,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:En,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Wt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.key-pattern\n \n \n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Dn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[]}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[D.required]],host:[e?e.host:null,[D.required]],port:[e?e.port:null,[D.required,D.min(1),D.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[D.required,D.min(1),D.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ne(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]}),this.subscriptions.push(this.mqttConfigForm.get("clientId").valueChanges.subscribe((e=>{ne(e)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1})})))}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}}e("MqttConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Dn,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Vn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=N,this.entityType=x}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[D.required]],targets:[e?e.targets:[],[D.required]]})}}e("NotificationConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vn,deps:[{token:G.Store},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Vn,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:He.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ke.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder}]}});class wn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[D.required]],topicName:[e?e.topicName:null,[D.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[D.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[D.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",wn),wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:wn,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Pe.FileInputComponent,selector:"tb-file-input",inputs:["label","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Wt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:wn,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Pn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[D.required]],port:[e?e.port:null,[D.required,D.min(1),D.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[D.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[D.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",Pn),Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Pn,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Re.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Wt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Pn,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Rn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(qt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[D.required]],requestMethod:[e?e.requestMethod:null,[D.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],trimDoubleQuotes:[!!e&&e.trimDoubleQuotes,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[D.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[D.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[D.required,D.min(1),D.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([D.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([D.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Rn,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:Wt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.trim-double-quotes\' | translate }}\n \n
tb.rulenode.trim-double-quotes-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class On extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([D.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([D.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([D.required,D.min(1),D.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([D.required,D.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[D.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[D.required,D.min(1),D.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:On,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:On,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Be.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:z.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Re.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Hn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[D.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[D.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([D.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Hn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Hn,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ue.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Kn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(S),this.slackChanelTypesTranslateMap=q}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[D.required]],conversationType:[e?e.conversationType:null,[D.required]],conversation:[e?e.conversation:null,[D.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([D.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kn,deps:[{token:G.Store},{token:E.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Kn,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ze.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:ze.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:_e.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.FormBuilder}]}});class Bn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[D.required]],accessKeyId:[e?e.accessKeyId:null,[D.required]],secretAccessKey:[e?e.secretAccessKey:null,[D.required]],region:[e?e.region:null,[D.required]]})}}e("SnsConfigComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Bn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Bn,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Un extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Lt,this.sqsQueueTypes=Object.keys(Lt),this.sqsQueueTypeTranslationsMap=kt}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[D.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[D.required]],delaySeconds:[e?e.delaySeconds:null,[D.min(0),D.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[D.required]],secretAccessKey:[e?e.secretAccessKey:null,[D.required]],region:[e?e.region:null,[D.required]]})}}e("SqsConfigComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Un,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Un,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Wt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n \n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class zn{}e("RulenodeCoreConfigExternalModule",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),zn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:zn,declarations:[Bn,Un,wn,En,Dn,Vn,Pn,Rn,On,Gn,Hn,Kn],imports:[K,L,Me,hn],exports:[Bn,Un,wn,En,Dn,Vn,Pn,Rn,On,Gn,Hn,Kn]}),zn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zn,imports:[K,L,Me,hn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:zn,decorators:[{type:l,args:[{declarations:[Bn,Un,wn,En,Dn,Vn,Pn,Rn,On,Gn,Hn,Kn],imports:[K,L,Me,hn],exports:[Bn,Un,wn,En,Dn,Vn,Pn,Rn,On,Gn,Hn,Kn]}]}]});class _n extends s{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.alarmStatusTranslationsMap=M,this.alarmStatusList=[],this.searchText="",this.displayStatusFn=this.displayStatus.bind(this);for(const e of Object.keys(A))this.alarmStatusList.push(A[e]);this.statusFormControl=new O(""),this.filteredAlarmStatus=this.statusFormControl.valueChanges.pipe(Le(""),Ce((e=>e||"")),ve((e=>this.fetchAlarmStatus(e))),ke())}ngOnInit(){super.ngOnInit()}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return this.searchText="",this.statusFormControl.patchValue("",{emitEvent:!0}),e}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e?e.alarmStatusList:null,[D.required]]})}displayStatus(e){return e?this.translate.instant(M.get(e)):void 0}fetchAlarmStatus(e){const t=this.getAlarmStatusList();if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ne(t.filter((t=>this.translate.instant(M.get(A[t])).toUpperCase().includes(e))))}return Ne(t)}alarmStatusSelected(e){this.addAlarmStatus(e.option.value),this.clear("")}removeAlarmStatus(e){const t=this.alarmStatusConfigForm.get("alarmStatusList").value;if(t){const n=t.indexOf(e);n>=0&&(t.splice(n,1),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}}addAlarmStatus(e){let t=this.alarmStatusConfigForm.get("alarmStatusList").value;t||(t=[]);-1===t.indexOf(e)&&(t.push(e),this.alarmStatusConfigForm.get("alarmStatusList").setValue(t))}getAlarmStatusList(){return this.alarmStatusList.filter((e=>-1===this.alarmStatusConfigForm.get("alarmStatusList").value.indexOf(e)))}onAlarmStatusInputFocus(){this.statusFormControl.updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.alarmStatusInput.nativeElement.value=e,this.statusFormControl.patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.alarmStatusInput.nativeElement.blur(),this.alarmStatusInput.nativeElement.focus()}),0)}}e("CheckAlarmStatusComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_n,deps:[{token:G.Store},{token:j.TranslateService},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:_n,selector:"tb-filter-node-check-alarm-status-config",viewQueries:[{propertyName:"alarmStatusInput",first:!0,predicate:["alarmStatusInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:fe.TbErrorComponent,selector:"tb-error",inputs:["error"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Te.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Te.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Te.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Ie.HighlightPipe,name:"highlight"},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n \n tb.rulenode.alarm-status-filter\n \n \n \n {{alarmStatusTranslationsMap.get(alarmStatus) | translate}}\n \n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-alarm-status-matching\n
\n
\n
\n
\n
\n \n
\n\n\n\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:j.TranslateService},{type:E.UntypedFormBuilder}]},propDecorators:{alarmStatusInput:[{type:o,args:["alarmStatusInput",{static:!1}]}]}});class jn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ie,le,se]}configForm(){return this.checkMessageConfigForm}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e?e.messageNames:null,[]],metadataNames:[e?e.metadataNames:null,[]],checkAllKeys:[!!e&&e.checkAllKeys,[]]})}validateConfig(){const e=this.checkMessageConfigForm.get("messageNames").value,t=this.checkMessageConfigForm.get("metadataNames").value;return e.length>0||t.length>0}removeMessageName(e){const t=this.checkMessageConfigForm.get("messageNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("messageNames").setValue(t,{emitEvent:!0}))}removeMetadataName(e){const t=this.checkMessageConfigForm.get("metadataNames").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.checkMessageConfigForm.get("metadataNames").setValue(t,{emitEvent:!0}))}addMessageName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("messageNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("messageNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}addMetadataName(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.checkMessageConfigForm.get("metadataNames").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.checkMessageConfigForm.get("metadataNames").setValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CheckMessageConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:jn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:jn,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n \n tb.rulenode.data-keys\n \n \n {{messageName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n tb.rulenode.metadata-keys\n \n \n {{metadataName}}\n close\n \n \n \n tb.rulenode.separator-hint\n \n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
tb.rulenode.check-all-keys-hint
\n
\n',styles:[":host label.tb-title{margin-bottom:-10px}\n"]}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class $n extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.keys(g),this.entitySearchDirectionTranslationsMap=y}configForm(){return this.checkRelationConfigForm}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[!!e&&e.checkForSingleEntity,[]],direction:[e?e.direction:null,[]],entityType:[e?e.entityType:null,e&&e.checkForSingleEntity?[D.required]:[]],entityId:[e?e.entityId:null,e&&e.checkForSingleEntity?[D.required]:[]],relationType:[e?e.relationType:null,[D.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[D.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[D.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$n,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:$n,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:je.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:pe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:De.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["label","floatLabel","required","disabled","subscriptSizing"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.check-relation-hint
\n \n relation.direction\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }}\n \n \n \n
\n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Qn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=lt,this.perimeterTypes=Object.keys(lt),this.perimeterTypeTranslationMap=st,this.rangeUnits=Object.keys(pt),this.rangeUnitTranslationMap=dt}configForm(){return this.geoFilterConfigForm}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[D.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[D.required]],perimeterType:[e?e.perimeterType:null,[D.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([D.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==lt.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([])):(this.geoFilterConfigForm.get("centerLatitude").setValidators([D.required,D.min(-90),D.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([D.required,D.min(-180),D.max(180)]),this.geoFilterConfigForm.get("range").setValidators([D.required,D.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([D.required])),t||n!==lt.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([D.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Qn,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:B.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:E.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-message-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Jn extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e?e.messageTypes:null,[D.required]]})}}e("MessageTypeConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Jn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Jn,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n
\n',dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:cn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Yn extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.TENANT,x.CUSTOMER,x.USER,x.DASHBOARD,x.RULE_CHAIN,x.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e?e.originatorTypes:null,[D.required]]})}}e("OriginatorTypeConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Yn,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Yn,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n
\n',dependencies:[{kind:"component",type:$e.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["label","floatLabel","required","disabled","subscriptSizing","allowedEntityTypes","ignoreAuthorityFilter"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class Wn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=W(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[D.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[D.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[D.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Wn,deps:[{token:G.Store},{token:E.UntypedFormBuilder},{token:X.NodeScriptTestService},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Wn,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:re.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ae.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder},{type:X.NodeScriptTestService},{type:j.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Xn extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=W(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[D.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===d.JS?[D.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===d.TBEL?[D.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.switchConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",r=this.switchConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.switchConfigForm.get(t).setValue(e)}))}onValidate(){this.switchConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xn,deps:[{token:G.Store},{token:E.UntypedFormBuilder},{token:X.NodeScriptTestService},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:Xn,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:re.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ae.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder},{type:X.NodeScriptTestService},{type:j.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Zn{}e("RuleNodeCoreConfigFilterModule",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Zn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:Zn,declarations:[jn,$n,Qn,Jn,Yn,Wn,Xn,_n],imports:[K,L,hn],exports:[jn,$n,Qn,Jn,Yn,Wn,Xn,_n]}),Zn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zn,imports:[K,L,hn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:Zn,decorators:[{type:l,args:[{declarations:[jn,$n,Qn,Jn,Yn,Wn,Xn,_n],imports:[K,L,hn],exports:[jn,$n,Qn,Jn,Yn,Wn,Xn,_n]}]}]});class er extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=at,this.originatorSources=Object.keys(at),this.originatorSourceTranslationMap=it,this.allowedEntityTypes=[x.DEVICE,x.ASSET,x.ENTITY_VIEW,x.USER,x.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[D.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===at.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([D.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===at.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([D.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([D.required,D.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:er,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:er,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:_.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:xn,selector:"tb-relations-query-config-old",inputs:["disabled","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.originator-source\n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n \n
\n
\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class tr extends s{constructor(e,t,n,r){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=r,this.tbelEnabled=W(this.store).tbelEnabled,this.scriptLanguage=d}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:d.JS,[D.required]],jsScript:[e?e.jsScript:null,[D.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==d.TBEL||this.tbelEnabled||(t=d.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===d.JS?[D.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===d.TBEL?[D.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=d.JS)),e}testScript(){const e=this.scriptConfigForm.get("scriptLang").value,t=e===d.JS?"jsScript":"tbelScript",n=e===d.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",r=this.scriptConfigForm.get(t).value;this.nodeScriptTestService.testNodeScript(r,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,n,e).subscribe((e=>{e&&this.scriptConfigForm.get(t).setValue(e)}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===d.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tr,deps:[{token:G.Store},{token:E.UntypedFormBuilder},{token:X.NodeScriptTestService},{token:j.TranslateService}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:tr,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:re.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:oe.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ae.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder},{type:X.NodeScriptTestService},{type:j.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class nr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",value:"false"},{name:"tb.mail-body-type.html",value:"true"},{name:"tb.mail-body-type.dynamic",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[D.required]],toTemplate:[e?e.toTemplate:null,[D.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[D.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null],bodyTemplate:[e?e.bodyTemplate:null,[D.required]]}),this.toEmailConfigForm.get("mailBodyType").valueChanges.pipe(Le([e?.subjectTemplate])).subscribe((e=>{"dynamic"===e?(this.toEmailConfigForm.get("isHtmlTemplate").patchValue("",{emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").setValidators(D.required)):this.toEmailConfigForm.get("isHtmlTemplate").clearValidators(),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity()}))}}e("ToEmailConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nr,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:nr,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:Q.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:J.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:j.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n \n \n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.cc-template\n \n \n \n \n tb.rulenode.bcc-template\n \n \n \n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n \n tb.rulenode.mail-body-type\n \n \n {{ type.name | translate }}\n \n \n \n \n tb.rulenode.dynamic-mail-body-type\n \n \n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class rr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ie,le,se]}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[D.required]],keys:[e?e.keys:null,[D.required]]})}configForm(){return this.copyKeysConfigForm}removeKey(e){const t=this.copyKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.copyKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.copyKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.copyKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("CopyKeysConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rr,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:rr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ze.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:ze.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n
{{\'tb.rulenode.copy-from\' | translate}}
\n \n \n {{\'tb.rulenode.data-to-metadata\' | translate}}\n \n \n {{\'tb.rulenode.metadata-to-data\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class or extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[D.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[D.required]]})}}e("RenameKeysConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:or,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:or,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:ze.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:ze.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Wt,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
{{ \'tb.rulenode.rename-keys-in\' | translate }}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class ar extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[D.required]]})}}e("NodeJsonPathConfigComponent",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ar,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ar,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatLabel,selector:"mat-label"},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ar,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n\n"}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class ir extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.separatorKeysCodes=[ie,le,se]}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({fromMetadata:[e?e.fromMetadata:null,[D.required]],keys:[e?e.keys:null,[D.required]]})}configForm(){return this.deleteKeysConfigForm}removeKey(e){const t=this.deleteKeysConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteKeysConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteKeysConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteKeysConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteKeysConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ir,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:ir,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:me.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:U.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:z.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:z.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:z.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ze.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:ze.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"component",type:ue.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ue.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ue.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ue.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:_.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"},{kind:"pipe",type:Je,name:"safeHtml"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n
{{\'tb.rulenode.delete-from\' | translate}}
\n \n \n {{\'tb.rulenode.data\' | translate}}\n \n \n {{\'tb.rulenode.metadata\' | translate}}\n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.keys-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class lr{}e("RulenodeCoreConfigTransformModule",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:lr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),lr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:lr,declarations:[er,tr,nr,rr,or,ar,ir],imports:[K,L,hn],exports:[er,tr,nr,rr,or,ar,ir]}),lr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:lr,imports:[K,L,hn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:lr,decorators:[{type:l,args:[{declarations:[er,tr,nr,rr,or,ar,ir],imports:[K,L,hn],exports:[er,tr,nr,rr,or,ar,ir]}]}]});class sr extends s{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=x}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[D.required]]})}}e("RuleChainInputComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:sr,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:sr,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:je.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:E.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class mr extends s{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:mr,deps:[{token:G.Store},{token:E.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.9",type:mr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:_.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:E.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:E.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:j.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:G.Store},{type:E.UntypedFormBuilder}]}});class ur{}e("RuleNodeCoreConfigFlowModule",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:ur,declarations:[sr,mr],imports:[K,L,hn],exports:[sr,mr]}),ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,imports:[K,L,hn]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:ur,decorators:[{type:l,args:[{declarations:[sr,mr],imports:[K,L,hn],exports:[sr,mr]}]}]});class pr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{"create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","output-message-type":"Output message type","output-message-type-required":"Output message type is required","output-message-type-max-length":"Output message type should be less than 256","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required!","limit-range":"Limit should be in a range from 2 to 1000!","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Time value should be in a range from 1 to 2147483647!","start-interval-value-required":"Start interval value is required!","end-interval-value-required":"End interval value is required!",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Notify device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-hint":"If the message arrives from the device, we will push it back to the device by default.","notify-device-delete-hint":"Send notification about deleted attributes to device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","add-timeseries-key":"Add timeseries key","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Hint: use regular expression to copy keys by pattern",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","key-name":"Key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Max relation level should be greater than 0 or unspecified!","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required!","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required!","target-key":"Target key","target-key-required":"Target key is required!","attr-mapping-required":"At least one mapping entry should be specified!","fields-mapping":"Fields mapping*","fields-mapping-required":"At least one field mapping should be specified.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","source-field":"Source field","source-field-required":"Source field is required!","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","body-template":"Body Template","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","trim-double-quotes":"Message without quotes","trim-double-quotes-hint":"If selected, request body message payload will be sent without double quotes, i.e. msg = message body","read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Hint: Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Hint: Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Hint: Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required!","end-interval-required":"Interval end is required!","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"entity-details":"Select entity details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","entity-details-list-empty":"No entity details selected!","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-key-name":"Latitude key name","longitude-key-name":"Longitude key name","latitude-key-name-required":"Latitude key name is required.","longitude-key-name-required":"Longitude key name is required.","fetch-perimeter-info-from-message-metadata":"Fetch perimeter information from message metadata","perimeter-key-name":"Perimeter key name","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Please, use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required!","output-value-key":"Output value key","output-value-key-required":"Output value key is required!","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15!","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-cashing":"Use cashing","use-cashing-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required!","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Hint: use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message body and ${metadataKey} to extract value from the message metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time series","message-body-type":"Message body","message-metadata-type":"Message metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-type-field-input":"Type","argument-type-field-input-required":"Argument type is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Hint: use 0 to convert result to integer","add-to-body-field-input":"Add to message body","add-to-metadata-field-input":"Add to message metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Hint: specify a mathematical expression to evaluate. For example, transform Fahrenheit to Celsius using (x - 32) / 1.8)","retained-message":"Retained","attributes-mapping":"Attributes mapping*","latest-telemetry-mapping":"Latest telemetry mapping*","add-mapped-attribute-to":"Add mapped attributes to:","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to:","add-mapped-fields-to":"Add mapped fields to:","add-selected-details-to":"Add selected details to:","clear-selected-details":"Clear selected details","clear-selected-keys":"Clear selected keys","fetch-credentials-to":"Fetch credentials to:","add-originator-attributes-to":"Add originator attributes to:","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound message metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell Failure","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to:",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output message metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end")!',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch:","mapping-of-customers":"Mapping of customer's:",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to:","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's:","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required"},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping entry","add-entry":"Add entry","unique-key-value-pair-error":"'{{valText}}' must be different from the current '{{keyText}}'"},"mail-body-type":{"plain-text":"Plain Text",html:"HTML",dynamic:"Dynamic"}}},!0)}(e)}}e("RuleNodeCoreConfigModule",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pr,deps:[{token:j.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),pr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.9",ngImport:t,type:pr,declarations:[Qe],imports:[K,L],exports:[Cn,Zn,An,zn,lr,ur,Qe]}),pr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pr,imports:[K,L,Cn,Zn,An,zn,lr,ur]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.9",ngImport:t,type:pr,decorators:[{type:l,args:[{declarations:[Qe],imports:[K,L],exports:[Cn,Zn,An,zn,lr,ur,Qe]}]}],ctorParameters:function(){return[{type:j.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map From 6d0b16e41c06220f325f1b8ebfad30b1f573d00a Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Wed, 14 Jun 2023 18:56:36 +0300 Subject: [PATCH 176/207] tbel: add parseBytesToDouble --- .../thingsboard/script/api/tbel/TbUtils.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index 10d48d582a..0708d1c959 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -16,6 +16,7 @@ package org.thingsboard.script.api.tbel; import com.google.common.primitives.Bytes; +import org.apache.commons.lang3.ArrayUtils; import org.mvel2.ExecutionContext; import org.mvel2.ParserConfiguration; import org.mvel2.execution.ExecutionArrayList; @@ -31,6 +32,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Base64; import java.util.Collection; import java.util.List; @@ -90,6 +92,14 @@ public class TbUtils { List.class, int.class, boolean.class))); parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", List.class, int.class))); + parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", + byte[].class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", + byte[].class, int.class))); + parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", + List.class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", + List.class, int.class))); parserConfig.addImport("toFixed", new MethodStub(TbUtils.class.getMethod("toFixed", double.class, int.class))); parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes", @@ -329,6 +339,39 @@ public class TbUtils { return parseBytesToFloat(Bytes.toArray(data), offset, bigEndian); } + + public static double parseBytesToDouble(byte[] data, int offset) { + return parseBytesToDouble(data, offset, true); + } + + public static double parseBytesToDouble(byte[] data, int offset, boolean bigEndian) { + if (data != null && data.length > 0) { + int length = 8; + if (offset > data.length) { + throw new IllegalArgumentException("Offset: " + offset + " is out of bounds for array with length: " + data.length + "!"); + } + if ((offset + length) > data.length) { + throw new IllegalArgumentException("Default length is always 4 bytes. Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!"); + } + + byte[] dataBytesArray = Arrays.copyOfRange(data, offset, (offset+length)); + if (!bigEndian) { + ArrayUtils.reverse(dataBytesArray); + } + return ByteBuffer.wrap(dataBytesArray).getDouble(); + } else { + throw new IllegalArgumentException("Array is null or array length is 0!"); + } + } + + public static double parseBytesToDouble(List data, int offset) { + return parseBytesToDouble(data, offset, true); + } + + public static double parseBytesToDouble(List data, int offset, boolean bigEndian) { + return parseBytesToDouble(Bytes.toArray(data), offset, bigEndian); + } + public static String bytesToHex(ExecutionArrayList bytesList) { byte[] bytes = new byte[bytesList.size()]; for (int i = 0; i < bytesList.size(); i++) { From b79176f3b89fa16dd55c5d6e12cddf7dc482bd4b Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Thu, 15 Jun 2023 16:50:31 +0300 Subject: [PATCH 177/207] tbel: add parseLong parseHexToLong parseBytesToLong toFixed (float.class) --- .../thingsboard/script/api/tbel/TbUtils.java | 190 ++++++++++++++---- 1 file changed, 149 insertions(+), 41 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index 0708d1c959..d275466b95 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -64,6 +64,10 @@ public class TbUtils { String.class))); parserConfig.addImport("parseInt", new MethodStub(TbUtils.class.getMethod("parseInt", String.class, int.class))); + parserConfig.addImport("parseLong", new MethodStub(TbUtils.class.getMethod("parseLong", + String.class))); + parserConfig.addImport("parseLong", new MethodStub(TbUtils.class.getMethod("parseLong", + String.class, int.class))); parserConfig.addImport("parseFloat", new MethodStub(TbUtils.class.getMethod("parseFloat", String.class))); parserConfig.addImport("parseDouble", new MethodStub(TbUtils.class.getMethod("parseDouble", @@ -76,6 +80,10 @@ public class TbUtils { String.class))); parserConfig.addImport("parseHexToInt", new MethodStub(TbUtils.class.getMethod("parseHexToInt", String.class, boolean.class))); + parserConfig.addImport("parseHexToLong", new MethodStub(TbUtils.class.getMethod("parseHexToLong", + String.class))); + parserConfig.addImport("parseHexToLong", new MethodStub(TbUtils.class.getMethod("parseHexToLong", + String.class, boolean.class))); parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt", List.class, int.class, int.class))); parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt", @@ -84,6 +92,14 @@ public class TbUtils { byte[].class, int.class, int.class))); parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt", byte[].class, int.class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToLong", new MethodStub(TbUtils.class.getMethod("parseBytesToLong", + List.class, int.class, int.class))); + parserConfig.addImport("parseBytesToLong", new MethodStub(TbUtils.class.getMethod("parseBytesToLong", + List.class, int.class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToLong", new MethodStub(TbUtils.class.getMethod("parseBytesToLong", + byte[].class, int.class, int.class))); + parserConfig.addImport("parseBytesToLong", new MethodStub(TbUtils.class.getMethod("parseBytesToLong", + byte[].class, int.class, int.class, boolean.class))); parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", byte[].class, int.class, boolean.class))); parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", @@ -92,16 +108,18 @@ public class TbUtils { List.class, int.class, boolean.class))); parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", List.class, int.class))); - parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", - byte[].class, int.class, boolean.class))); parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", byte[].class, int.class))); parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", - List.class, int.class, boolean.class))); + byte[].class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", + List.class, int.class))); parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", - List.class, int.class))); + List.class, int.class, boolean.class))); parserConfig.addImport("toFixed", new MethodStub(TbUtils.class.getMethod("toFixed", double.class, int.class))); + parserConfig.addImport("toFixed", new MethodStub(TbUtils.class.getMethod("toFixed", + float.class, int.class))); parserConfig.addImport("hexToBytes", new MethodStub(TbUtils.class.getMethod("hexToBytes", ExecutionContext.class, String.class))); parserConfig.addImport("base64ToHex", new MethodStub(TbUtils.class.getMethod("base64ToHex", @@ -204,6 +222,38 @@ public class TbUtils { return null; } + public static Long parseLong(String value) { + if (value != null) { + try { + int radix = 10; + if (isHexadecimal(value)) { + radix = 16; + } + return Long.parseLong(prepareNumberString(value), radix); + } catch (NumberFormatException e) { + Double d = parseDouble(value); + if (d != null) { + return d.longValue(); + } + } + } + return null; + } + + public static Long parseLong(String value, int radix) { + if (value != null) { + try { + return Long.parseLong(prepareNumberString(value), radix); + } catch (NumberFormatException e) { + Double d = parseDouble(value); + if (d != null) { + return d.longValue(); + } + } + } + return null; + } + public static Float parseFloat(String value) { if (value != null) { try { @@ -251,6 +301,33 @@ public class TbUtils { return parseBytesToInt(data, 0, data.length, bigEndian); } + public static long parseLittleEndianHexToLong(String hex) { + return parseHexToLong(hex, false); + } + + public static long parseBigEndianHexToLong(String hex) { + return parseHexToInt(hex, true); + } + + public static long parseHexToLong(String hex) { + return parseHexToInt(hex, true); + } + + public static long parseHexToLong(String hex, boolean bigEndian) { + int length = hex.length(); + if (length > 16) { + throw new IllegalArgumentException("Hex string is too large. Maximum 8 symbols allowed."); + } + if (length % 2 > 0) { + throw new IllegalArgumentException("Hex string must be even-length."); + } + byte[] data = new byte[length / 2]; + for (int i = 0; i < length; i += 2) { + data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16)); + } + return parseBytesToLong(data, 0, data.length, bigEndian); + } + public static ExecutionArrayList hexToBytes(ExecutionContext ctx, String hex) { int len = hex.length(); if (len % 2 > 0) { @@ -312,66 +389,93 @@ public class TbUtils { return bb.getInt(); } - public static float parseBytesToFloat(byte[] data, int offset) { - return parseBytesToFloat(data, offset, true); + public static long parseBytesToLong(List data, int offset, int length) { + return parseBytesToLong(data, offset, length, true); } - public static float parseBytesToFloat(byte[] data, int offset, boolean bigEndian) { - if (data != null && data.length > 0) { - int length = 4; - if (offset > data.length) { - throw new IllegalArgumentException("Offset: " + offset + " is out of bounds for array with length: " + data.length + "!"); - } - if ((offset + length) > data.length) { - throw new IllegalArgumentException("Default length is always 4 bytes. Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!"); - } - int i = parseBytesToInt(data, offset, length, bigEndian); - return Float.intBitsToFloat(i); - } else { - throw new IllegalArgumentException("Array is null or array length is 0!"); + public static long parseBytesToLong(List data, int offset, int length, boolean bigEndian) { + final byte[] bytes = new byte[data.size()]; + for (int i = 0; i < bytes.length; i++) { + bytes[i] = data.get(i); } + return parseBytesToLong(bytes, offset, length, bigEndian); } - public static float parseBytesToFloat(List data, int offset) { + + public static long parseBytesToLong(byte[] data, int offset, int length) { + return parseBytesToLong(data, offset, length, true); + } + + public static long parseBytesToLong(byte[] data, int offset, int length, boolean bigEndian) { + if (offset > data.length) { + throw new IllegalArgumentException("Offset: " + offset + " is out of bounds for array with length: " + data.length + "!"); + } + if (length > 8) { + throw new IllegalArgumentException("Length: " + length + " is too large. Maximum 4 bytes is allowed!"); + } + if (offset + length > data.length) { + throw new IllegalArgumentException("Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!"); + } + var bb = ByteBuffer.allocate(8); + if (!bigEndian) { + bb.order(ByteOrder.LITTLE_ENDIAN); + } + bb.position(bigEndian ? 8 - length : 0); + bb.put(data, offset, length); + bb.position(0); + return bb.getLong(); + } + + public static float parseBytesToFloat(byte[] data, int offset) { return parseBytesToFloat(data, offset, true); } + public static float parseBytesToFloat(List data, int offset) { + return parseBytesToFloat(data, offset,true); + } + public static float parseBytesToFloat(List data, int offset, boolean bigEndian) { return parseBytesToFloat(Bytes.toArray(data), offset, bigEndian); } - - public static double parseBytesToDouble(byte[] data, int offset) { - return parseBytesToDouble(data, offset, true); + public static float parseBytesToFloat(byte[] data, int offset, boolean bigEndian) { + byte[] bytesToNumber = prepareBytesToNumber (data, offset, 4, bigEndian); + return ByteBuffer.wrap(bytesToNumber).getFloat(); } - public static double parseBytesToDouble(byte[] data, int offset, boolean bigEndian) { - if (data != null && data.length > 0) { - int length = 8; - if (offset > data.length) { - throw new IllegalArgumentException("Offset: " + offset + " is out of bounds for array with length: " + data.length + "!"); - } - if ((offset + length) > data.length) { - throw new IllegalArgumentException("Default length is always 4 bytes. Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!"); - } - byte[] dataBytesArray = Arrays.copyOfRange(data, offset, (offset+length)); - if (!bigEndian) { - ArrayUtils.reverse(dataBytesArray); - } - return ByteBuffer.wrap(dataBytesArray).getDouble(); - } else { - throw new IllegalArgumentException("Array is null or array length is 0!"); - } + public static double parseBytesToDouble(byte[] data, int offset) { + return parseBytesToDouble(data, offset, true); } public static double parseBytesToDouble(List data, int offset) { - return parseBytesToDouble(data, offset, true); + return parseBytesToDouble(data, offset,true); } public static double parseBytesToDouble(List data, int offset, boolean bigEndian) { return parseBytesToDouble(Bytes.toArray(data), offset, bigEndian); } + public static double parseBytesToDouble(byte[] data, int offset, boolean bigEndian) { + byte[] bytesToNumber = prepareBytesToNumber (data, offset, 8, bigEndian); + return ByteBuffer.wrap(bytesToNumber).getDouble(); + } + + private static byte [] prepareBytesToNumber(byte[] data, int offset, int length, boolean bigEndian) { + if (offset > data.length) { + throw new IllegalArgumentException("Offset: " + offset + " is out of bounds for array with length: " + data.length + "!"); + } + if ((offset + length) > data.length) { + throw new IllegalArgumentException("Default length is always " + length + " bytes. Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!"); + } + byte[] bytesToNumber = new byte[length]; + byte[] dataBytesArray = Arrays.copyOfRange(data, offset, (offset+length)); + if (!bigEndian) { + ArrayUtils.reverse(dataBytesArray); + } + System.arraycopy(dataBytesArray, 0, bytesToNumber, 0, length); + return bytesToNumber; + } + public static String bytesToHex(ExecutionArrayList bytesList) { byte[] bytes = new byte[bytesList.size()]; for (int i = 0; i < bytesList.size(); i++) { @@ -394,6 +498,10 @@ public class TbUtils { return BigDecimal.valueOf(value).setScale(precision, RoundingMode.HALF_UP).doubleValue(); } + public static float toFixed(float value, int precision) { + return BigDecimal.valueOf(value).setScale(precision, RoundingMode.HALF_UP).floatValue(); + } + private static boolean isHexadecimal(String value) { return value != null && (value.contains("0x") || value.contains("0X")); } From 59dfb4f4e1b11a18cd409ba058b6f57d084351d1 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Thu, 15 Jun 2023 17:02:34 +0300 Subject: [PATCH 178/207] tbel: refactoring prepareBytesToNumber --- .../main/java/org/thingsboard/script/api/tbel/TbUtils.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index d275466b95..dec4ff6f15 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -467,13 +467,11 @@ public class TbUtils { if ((offset + length) > data.length) { throw new IllegalArgumentException("Default length is always " + length + " bytes. Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!"); } - byte[] bytesToNumber = new byte[length]; byte[] dataBytesArray = Arrays.copyOfRange(data, offset, (offset+length)); if (!bigEndian) { ArrayUtils.reverse(dataBytesArray); } - System.arraycopy(dataBytesArray, 0, bytesToNumber, 0, length); - return bytesToNumber; + return dataBytesArray; } public static String bytesToHex(ExecutionArrayList bytesList) { From f15d84e44aff576ed4208f6d7be5f601d6e882d6 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Thu, 15 Jun 2023 19:20:50 +0300 Subject: [PATCH 179/207] tbel: add parseHexToLong, Float, Double --- .../thingsboard/script/api/tbel/TbUtils.java | 109 +++++++++++++----- 1 file changed, 79 insertions(+), 30 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index dec4ff6f15..aced1512b6 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -80,10 +80,6 @@ public class TbUtils { String.class))); parserConfig.addImport("parseHexToInt", new MethodStub(TbUtils.class.getMethod("parseHexToInt", String.class, boolean.class))); - parserConfig.addImport("parseHexToLong", new MethodStub(TbUtils.class.getMethod("parseHexToLong", - String.class))); - parserConfig.addImport("parseHexToLong", new MethodStub(TbUtils.class.getMethod("parseHexToLong", - String.class, boolean.class))); parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt", List.class, int.class, int.class))); parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt", @@ -92,6 +88,14 @@ public class TbUtils { byte[].class, int.class, int.class))); parserConfig.addImport("parseBytesToInt", new MethodStub(TbUtils.class.getMethod("parseBytesToInt", byte[].class, int.class, int.class, boolean.class))); + parserConfig.addImport("parseLittleEndianHexToLong", new MethodStub(TbUtils.class.getMethod("parseLittleEndianHexToLong", + String.class))); + parserConfig.addImport("parseBigEndianHexToLong", new MethodStub(TbUtils.class.getMethod("parseBigEndianHexToLong", + String.class))); + parserConfig.addImport("parseHexToLong", new MethodStub(TbUtils.class.getMethod("parseHexToLong", + String.class))); + parserConfig.addImport("parseHexToLong", new MethodStub(TbUtils.class.getMethod("parseHexToLong", + String.class, boolean.class))); parserConfig.addImport("parseBytesToLong", new MethodStub(TbUtils.class.getMethod("parseBytesToLong", List.class, int.class, int.class))); parserConfig.addImport("parseBytesToLong", new MethodStub(TbUtils.class.getMethod("parseBytesToLong", @@ -100,20 +104,36 @@ public class TbUtils { byte[].class, int.class, int.class))); parserConfig.addImport("parseBytesToLong", new MethodStub(TbUtils.class.getMethod("parseBytesToLong", byte[].class, int.class, int.class, boolean.class))); + parserConfig.addImport("parseLittleEndianHexToFloat", new MethodStub(TbUtils.class.getMethod("parseLittleEndianHexToFloat", + String.class))); + parserConfig.addImport("parseBigEndianHexToFloat", new MethodStub(TbUtils.class.getMethod("parseBigEndianHexToFloat", + String.class))); + parserConfig.addImport("parseHexToFloat", new MethodStub(TbUtils.class.getMethod("parseHexToFloat", + String.class))); + parserConfig.addImport("parseHexToFloat", new MethodStub(TbUtils.class.getMethod("parseHexToFloat", + String.class, boolean.class))); parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", byte[].class, int.class, boolean.class))); parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", byte[].class, int.class))); - parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", - List.class, int.class, boolean.class))); + parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", + List.class, int.class, boolean.class))); parserConfig.addImport("parseBytesToFloat", new MethodStub(TbUtils.class.getMethod("parseBytesToFloat", List.class, int.class))); + parserConfig.addImport("parseLittleEndianHexToDouble", new MethodStub(TbUtils.class.getMethod("parseLittleEndianHexToDouble", + String.class))); + parserConfig.addImport("parseBigEndianHexToDouble", new MethodStub(TbUtils.class.getMethod("parseBigEndianHexToDouble", + String.class))); + parserConfig.addImport("parseHexToDouble", new MethodStub(TbUtils.class.getMethod("parseHexToDouble", + String.class))); + parserConfig.addImport("parseHexToDouble", new MethodStub(TbUtils.class.getMethod("parseHexToDouble", + String.class, boolean.class))); parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", byte[].class, int.class))); - parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", + parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", byte[].class, int.class, boolean.class))); - parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", - List.class, int.class))); + parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", + List.class, int.class))); parserConfig.addImport("parseBytesToDouble", new MethodStub(TbUtils.class.getMethod("parseBytesToDouble", List.class, int.class, boolean.class))); parserConfig.addImport("toFixed", new MethodStub(TbUtils.class.getMethod("toFixed", @@ -287,17 +307,7 @@ public class TbUtils { } public static int parseHexToInt(String hex, boolean bigEndian) { - int length = hex.length(); - if (length > 8) { - throw new IllegalArgumentException("Hex string is too large. Maximum 8 symbols allowed."); - } - if (length % 2 > 0) { - throw new IllegalArgumentException("Hex string must be even-length."); - } - byte[] data = new byte[length / 2]; - for (int i = 0; i < length; i += 2) { - data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16)); - } + byte[] data = prepareHexToBytesNumber(hex, 8); return parseBytesToInt(data, 0, data.length, bigEndian); } @@ -306,16 +316,55 @@ public class TbUtils { } public static long parseBigEndianHexToLong(String hex) { - return parseHexToInt(hex, true); + return parseHexToLong(hex, true); } public static long parseHexToLong(String hex) { - return parseHexToInt(hex, true); + return parseHexToLong(hex, true); } public static long parseHexToLong(String hex, boolean bigEndian) { + byte[] data = prepareHexToBytesNumber(hex, 16); + return parseBytesToLong(data, 0, data.length, bigEndian); + } + + public static float parseLittleEndianHexToFloat(String hex) { + return parseHexToFloat(hex, false); + } + + public static float parseBigEndianHexToFloat(String hex) { + return parseHexToFloat(hex, true); + } + + public static float parseHexToFloat(String hex) { + return parseHexToFloat(hex, true); + } + + public static float parseHexToFloat(String hex, boolean bigEndian) { + byte[] data = prepareHexToBytesNumber(hex, 8); + return parseBytesToFloat(data, 0, bigEndian); + } + + public static double parseLittleEndianHexToDouble(String hex) { + return parseHexToDouble(hex, false); + } + + public static double parseBigEndianHexToDouble(String hex) { + return parseHexToDouble(hex, true); + } + + public static double parseHexToDouble(String hex) { + return parseHexToDouble(hex, true); + } + + public static double parseHexToDouble(String hex, boolean bigEndian) { + byte[] data = prepareHexToBytesNumber(hex, 16); + return parseBytesToDouble(data, 0, bigEndian); + } + + private static byte[] prepareHexToBytesNumber(String hex, int len) { int length = hex.length(); - if (length > 16) { + if (length > len) { throw new IllegalArgumentException("Hex string is too large. Maximum 8 symbols allowed."); } if (length % 2 > 0) { @@ -325,7 +374,7 @@ public class TbUtils { for (int i = 0; i < length; i += 2) { data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16)); } - return parseBytesToLong(data, 0, data.length, bigEndian); + return data; } public static ExecutionArrayList hexToBytes(ExecutionContext ctx, String hex) { @@ -430,7 +479,7 @@ public class TbUtils { } public static float parseBytesToFloat(List data, int offset) { - return parseBytesToFloat(data, offset,true); + return parseBytesToFloat(data, offset, true); } public static float parseBytesToFloat(List data, int offset, boolean bigEndian) { @@ -438,7 +487,7 @@ public class TbUtils { } public static float parseBytesToFloat(byte[] data, int offset, boolean bigEndian) { - byte[] bytesToNumber = prepareBytesToNumber (data, offset, 4, bigEndian); + byte[] bytesToNumber = prepareBytesToNumber(data, offset, 4, bigEndian); return ByteBuffer.wrap(bytesToNumber).getFloat(); } @@ -448,7 +497,7 @@ public class TbUtils { } public static double parseBytesToDouble(List data, int offset) { - return parseBytesToDouble(data, offset,true); + return parseBytesToDouble(data, offset, true); } public static double parseBytesToDouble(List data, int offset, boolean bigEndian) { @@ -456,18 +505,18 @@ public class TbUtils { } public static double parseBytesToDouble(byte[] data, int offset, boolean bigEndian) { - byte[] bytesToNumber = prepareBytesToNumber (data, offset, 8, bigEndian); + byte[] bytesToNumber = prepareBytesToNumber(data, offset, 8, bigEndian); return ByteBuffer.wrap(bytesToNumber).getDouble(); } - private static byte [] prepareBytesToNumber(byte[] data, int offset, int length, boolean bigEndian) { + private static byte[] prepareBytesToNumber(byte[] data, int offset, int length, boolean bigEndian) { if (offset > data.length) { throw new IllegalArgumentException("Offset: " + offset + " is out of bounds for array with length: " + data.length + "!"); } if ((offset + length) > data.length) { throw new IllegalArgumentException("Default length is always " + length + " bytes. Offset: " + offset + " and Length: " + length + " is out of bounds for array with length: " + data.length + "!"); } - byte[] dataBytesArray = Arrays.copyOfRange(data, offset, (offset+length)); + byte[] dataBytesArray = Arrays.copyOfRange(data, offset, (offset + length)); if (!bigEndian) { ArrayUtils.reverse(dataBytesArray); } From 35dfa1e7bd82d9bb1adf75b6d5ceb9ad3cf4ea72 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 16 Jun 2023 18:57:20 +0300 Subject: [PATCH 180/207] tbel: add parseLong Test --- .../thingsboard/script/api/tbel/TbUtils.java | 104 +++++++++++------- .../script/api/tbel/TbUtilsTest.java | 93 ++++++++++++++++ 2 files changed, 155 insertions(+), 42 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index aced1512b6..b337612011 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.StringUtils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; +import java.math.BigInteger; import java.math.RoundingMode; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -211,69 +212,73 @@ public class TbUtils { } public static Integer parseInt(String value) { - if (value != null) { - try { - int radix = 10; - if (isHexadecimal(value)) { - radix = 16; - } - return Integer.parseInt(prepareNumberString(value), radix); - } catch (NumberFormatException e) { - Float f = parseFloat(value); - if (f != null) { - return f.intValue(); - } - } - } - return null; + int radix = getRadix(value); + return parseInt(value, radix); } public static Integer parseInt(String value, int radix) { - if (value != null) { + if (StringUtils.isNotBlank(value)) { try { - return Integer.parseInt(prepareNumberString(value), radix); - } catch (NumberFormatException e) { - Float f = parseFloat(value); - if (f != null) { - return f.intValue(); + String valueP = prepareNumberString(value); + isValidRadix(valueP, radix); + try { + return Integer.parseInt(valueP, radix); + } catch (NumberFormatException e) { + BigInteger bi = new BigInteger(valueP, radix); + if (bi.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) + throw new NumberFormatException("Value \"" + value + "\" is greater than the maximum Integer value " + Integer.MAX_VALUE + " !"); + if (bi.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0) + throw new NumberFormatException("Value \"" + value + "\" is less than the minimum Integer value " + Integer.MIN_VALUE + " !"); + Float f = parseFloat(valueP); + if (f != null) { + return f.intValue(); + } else { + throw new NumberFormatException(e.getMessage()); + } } + } catch (NumberFormatException e) { + throw new NumberFormatException(e.getMessage()); } } return null; } public static Long parseLong(String value) { - if (value != null) { - try { - int radix = 10; - if (isHexadecimal(value)) { - radix = 16; - } - return Long.parseLong(prepareNumberString(value), radix); - } catch (NumberFormatException e) { - Double d = parseDouble(value); - if (d != null) { - return d.longValue(); - } - } - } - return null; + int radix = getRadix(value); + return parseLong(value, radix); } public static Long parseLong(String value, int radix) { - if (value != null) { + if (StringUtils.isNotBlank(value)) { try { - return Long.parseLong(prepareNumberString(value), radix); - } catch (NumberFormatException e) { - Double d = parseDouble(value); - if (d != null) { - return d.longValue(); + String valueP = prepareNumberString(value); + isValidRadix(valueP, radix); + try { + return Long.parseLong(valueP, radix); + } catch (NumberFormatException e) { + BigInteger bi = new BigInteger(valueP, radix); + if (bi.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) + throw new NumberFormatException("Value \"" + value + "\"is greater than the maximum Long value " + Long.MAX_VALUE + " !"); + if (bi.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) < 0) + throw new NumberFormatException("Value \"" + value + "\" is less than the minimum Long value " + Long.MIN_VALUE + " !"); + Double dd = parseDouble(valueP); + if (dd != null) { + return dd.longValue(); + } else { + throw new NumberFormatException(e.getMessage()); + } } + } catch (NumberFormatException e) { + throw new NumberFormatException(e.getMessage()); } } return null; } + private static int getRadix(String value, int... radixS) { + return radixS.length > 0 ? radixS[0] : isHexadecimal(value) ? 16 : 10; + } + public static Float parseFloat(String value) { if (value != null) { try { @@ -622,4 +627,19 @@ public class TbUtils { } } } + + public static boolean isValidRadix(String value, int radix) { + for (int i = 0; i < value.length(); i++) { + if (i == 0 && value.charAt(i) == '-') { + if (value.length() == 1) + throw new NumberFormatException("Failed radix [" + radix + "] for value: \"" + value + "\"!"); + else + continue; + } + if (Character.digit(value.charAt(i), radix) < 0) + throw new NumberFormatException("Failed radix: [" + radix + "] for value: \"" + value + "\"!"); + } + return true; + } + } diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java index 82cd74ca30..35a8936e4b 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java @@ -26,6 +26,7 @@ import org.mvel2.SandboxedParserConfiguration; import org.mvel2.execution.ExecutionArrayList; import org.mvel2.execution.ExecutionHashMap; +import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Calendar; @@ -182,6 +183,98 @@ public class TbUtilsTest { Assert.assertEquals(expectedMapWithoutPaths, actualMapWithoutPaths); } + @Test + public void parseInt() { + Assert.assertNull(TbUtils.parseInt(null)); + Assert.assertNull(TbUtils.parseInt("")); + Assert.assertNull(TbUtils.parseInt(" ")); + + Assert.assertEquals(java.util.Optional.of(0).get(), TbUtils.parseInt("0")); + Assert.assertEquals(java.util.Optional.of(0).get(), TbUtils.parseInt("-0")); + Assert.assertEquals(java.util.Optional.of(473).get(), TbUtils.parseInt("473")); + Assert.assertEquals(java.util.Optional.of(-255).get(), TbUtils.parseInt("-0xFF")); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("FF")); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("0xFG")); + + Assert.assertEquals(java.util.Optional.of(102).get(), TbUtils.parseInt("1100110", 2)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("1100210", 2)); + + Assert.assertEquals(java.util.Optional.of(63).get(), TbUtils.parseInt("77", 8)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("18", 8)); + + Assert.assertEquals(java.util.Optional.of(-255).get(), TbUtils.parseInt("-FF", 16)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("FG", 16)); + + + Assert.assertEquals(java.util.Optional.of(Integer.MAX_VALUE).get(), TbUtils.parseInt(Integer.toString(Integer.MAX_VALUE), 10)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt(BigInteger.valueOf(Integer.MAX_VALUE).add(BigInteger.valueOf(1)).toString(10), 10)); + Assert.assertEquals(java.util.Optional.of(Integer.MIN_VALUE).get(), TbUtils.parseInt(Integer.toString(Integer.MIN_VALUE), 10)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt(BigInteger.valueOf(Integer.MIN_VALUE).subtract(BigInteger.valueOf(1)).toString(10), 10)); + + Assert.assertEquals(java.util.Optional.of(506070563).get(), TbUtils.parseInt("KonaIn", 30)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("KonaIn", 10)); + } + + @Test + public void parseLong() { + Assert.assertNull(TbUtils.parseLong(null)); + Assert.assertNull(TbUtils.parseLong("")); + Assert.assertNull(TbUtils.parseLong(" ")); + + Assert.assertEquals(java.util.Optional.of(0L).get(), TbUtils.parseLong("0")); + Assert.assertEquals(java.util.Optional.of(0L).get(), TbUtils.parseLong("-0")); + Assert.assertEquals(java.util.Optional.of(473L).get(), TbUtils.parseLong("473")); + Assert.assertEquals(java.util.Optional.of(-65535L).get(), TbUtils.parseLong("-0xFFFF")); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("FFFF")); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("0xFGFF")); + + Assert.assertEquals(java.util.Optional.of(13158L).get(), TbUtils.parseLong("11001101100110", 2)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong("11001101100210", 2)); + + Assert.assertEquals(java.util.Optional.of(9223372036854775807L).get(), TbUtils.parseLong("777777777777777777777", 8)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong("1787", 8)); + + Assert.assertEquals(java.util.Optional.of(-255L).get(), TbUtils.parseLong("-FF", 16)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong("FG", 16)); + + + Assert.assertEquals(java.util.Optional.of(Long.MAX_VALUE).get(), TbUtils.parseLong(Long.toString(Long.MAX_VALUE), 10)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong(BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.valueOf(1)).toString(10), 10)); + Assert.assertEquals(java.util.Optional.of(Long.MIN_VALUE).get(), TbUtils.parseLong(Long.toString(Long.MIN_VALUE), 10)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong(BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.valueOf(1)).toString(10), 10)); + + Assert.assertEquals(java.util.Optional.of(218840926543L).get(), TbUtils.parseLong("KonaLong", 27)); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong("KonaLong", 10)); + } + + + // parseLong String.class, int.class +// parseLittleEndianHexToLong String.class + // parseBigEndianHexToLong String.class + // parseHexToLong String.class + // parseHexToLong String.class boolean.class + // parseBytesToLong List.class, int.class, int.class + // parseBytesToLong List.class, int.class, int.class, boolean.class + // parseBytesToLong byte[].class, int.class, int.class + // parseBytesToLong byte[].class, int.class, int.class, boolean.class + // parseLittleEndianHexToFloat String.class + // parseBigEndianHexToFloat String.class + // parseHexToFloat String.class + // parseHexToFloat String.class boolean.class + // parseBytesToFloat byte[].class, int.class, boolean.class + // parseBytesToFloat byte[].class, int.class + // parseBytesToFloat List.class, int.class, boolean.class + // parseBytesToFloat List.class, int.class + // toFixed float.class, int.class + // parseLittleEndianHexToDouble String.class + // parseBigEndianHexToDouble String.class + // parseHexToDouble String.class + // parseHexToDouble String.class boolean.class + // parseBytesToDouble byte[].class, int.class + // parseBytesToDouble byte[].class, int.class, boolean.class + // parseBytesToDouble List.class, int.class + // parseBytesToDouble List.class, int.class boolean.class + private static String keyToValue(String key, String extraSymbol) { return key + "Value" + (extraSymbol == null ? "" : extraSymbol); From a5990599551233bfc4daec1d3cf3268ea1951888 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Mon, 19 Jun 2023 13:31:04 +0300 Subject: [PATCH 181/207] UI: Fixed notify again dialog with template --- .../sent/sent-notification-dialog.componet.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts index 4846cd063d..765404b880 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts @@ -154,6 +154,7 @@ export class SentNotificationDialogComponent extends let useTemplate = true; if (isDefinedAndNotNull(this.data.request.template)) { useTemplate = false; + this.refreshAllowDeliveryMethod(); // eslint-disable-next-line guard-for-in for (const method in this.data.request.template.configuration.deliveryMethodsTemplates) { this.deliveryMethodFormsMap.get(NotificationDeliveryMethod[method]) @@ -162,8 +163,6 @@ export class SentNotificationDialogComponent extends } this.notificationRequestForm.get('useTemplate').setValue(useTemplate, {onlySelf : true}); } - - this.refreshAllowDeliveryMethod(); } ngOnDestroy() { @@ -343,13 +342,15 @@ export class SentNotificationDialogComponent extends } private updateDeliveryMethodsDisableState() { - this.notificationDeliveryMethods.forEach(method => { - if (this.allowNotificationDeliveryMethods.includes(method)) { - this.getDeliveryMethodsTemplatesControl(method).enable({emitEvent: true}); - } else { - this.getDeliveryMethodsTemplatesControl(method).disable({emitEvent: true}); - this.getDeliveryMethodsTemplatesControl(method).setValue(false, {emitEvent: true}); //used for notify again - } - }); + if (this.allowNotificationDeliveryMethods) { + this.notificationDeliveryMethods.forEach(method => { + if (this.allowNotificationDeliveryMethods.includes(method)) { + this.getDeliveryMethodsTemplatesControl(method).enable({emitEvent: true}); + } else { + this.getDeliveryMethodsTemplatesControl(method).disable({emitEvent: true}); + this.getDeliveryMethodsTemplatesControl(method).setValue(false, {emitEvent: true}); //used for notify again + } + }); + } } } From 6894ffb8a99b85fabd9c2a21298bfea11de43f95 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 19 Jun 2023 17:38:41 +0300 Subject: [PATCH 182/207] tbel: add Tests - long, float, double --- .../script/api/tbel/TbUtilsTest.java | 134 +++++++++++++----- 1 file changed, 101 insertions(+), 33 deletions(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java index 35a8936e4b..e2f239f30e 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java @@ -15,6 +15,7 @@ */ package org.thingsboard.script.api.tbel; +import com.google.common.primitives.Bytes; import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; @@ -39,6 +40,23 @@ public class TbUtilsTest { private ExecutionContext ctx; + private final String intValHex = "41EA62CC"; + private final float floatVal = 29.29824f; + private final String floatValStr = "29.29824"; + + + private final String floatValHexRev = "CC62EA41"; + private final float floatValRev = -5.948442E7f; + + private final long longVal = 0x409B04B10CB295EAL; + private final String longValHex = "409B04B10CB295EA"; + private final long longValRev = 0xEA95B20CB1049B40L; + private final String longValHexRev = "EA95B20CB1049B40"; + private final String doubleValStr = "1729.1729"; + private final double doubleVal = 1729.1729; + private final double doubleValRev = -2.7208640774822924E205; + + @Before public void before() { SandboxedParserConfiguration parserConfig = ParserContext.enableSandboxedMode(); @@ -63,6 +81,7 @@ public class TbUtilsTest { @Test public void parseHexToInt() { Assert.assertEquals(0xAB, TbUtils.parseHexToInt("AB")); + Assert.assertEquals(0xABBA, TbUtils.parseHexToInt("ABBA", true)); Assert.assertEquals(0xBAAB, TbUtils.parseHexToInt("ABBA", false)); Assert.assertEquals(0xAABBCC, TbUtils.parseHexToInt("AABBCC", true)); @@ -215,6 +234,37 @@ public class TbUtilsTest { Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("KonaIn", 10)); } + @Test + public void parseFloat() { + Assert.assertEquals(java.util.Optional.of(floatVal).get(), TbUtils.parseFloat(floatValStr)); + } + + @Test + public void toFixedFloat() { + float actualF = TbUtils.toFixed(floatVal, 3); + Assert.assertEquals(1, Float.compare(floatVal, actualF)); + Assert.assertEquals(0, Float.compare(29.298f, actualF)); + } + + @Test + public void parseHexToFloat() { + Assert.assertEquals(0, Float.compare(floatVal, TbUtils.parseHexToFloat(intValHex))); + Assert.assertEquals(0, Float.compare(floatValRev, TbUtils.parseHexToFloat(intValHex, false))); + Assert.assertEquals(0, Float.compare(floatVal, TbUtils.parseBigEndianHexToFloat(intValHex))); + Assert.assertEquals(0, Float.compare(floatVal, TbUtils.parseLittleEndianHexToFloat(floatValHexRev))); + } + + @Test + public void arseBytesToFloat() { + byte[] floatValByte = {65, -22, 98, -52}; + Assert.assertEquals(0, Float.compare(floatVal, TbUtils.parseBytesToFloat(floatValByte, 0))); + Assert.assertEquals(0, Float.compare(floatValRev, TbUtils.parseBytesToFloat(floatValByte, 0, false))); + + List floatVaList = Bytes.asList(floatValByte); + Assert.assertEquals(0, Float.compare(floatVal, TbUtils.parseBytesToFloat(floatVaList, 0))); + Assert.assertEquals(0, Float.compare(floatValRev, TbUtils.parseBytesToFloat(floatVaList, 0, false))); + } + @Test public void parseLong() { Assert.assertNull(TbUtils.parseLong(null)); @@ -225,8 +275,8 @@ public class TbUtilsTest { Assert.assertEquals(java.util.Optional.of(0L).get(), TbUtils.parseLong("-0")); Assert.assertEquals(java.util.Optional.of(473L).get(), TbUtils.parseLong("473")); Assert.assertEquals(java.util.Optional.of(-65535L).get(), TbUtils.parseLong("-0xFFFF")); - Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("FFFF")); - Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseInt("0xFGFF")); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong("FFFFFFFF")); + Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong("0xFGFFFFFF")); Assert.assertEquals(java.util.Optional.of(13158L).get(), TbUtils.parseLong("11001101100110", 2)); Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong("11001101100210", 2)); @@ -247,37 +297,55 @@ public class TbUtilsTest { Assert.assertThrows(NumberFormatException.class, () -> TbUtils.parseLong("KonaLong", 10)); } + @Test + public void parseHexToLong() { + Assert.assertEquals(longVal, TbUtils.parseHexToLong(longValHex)); + Assert.assertEquals(longVal, TbUtils.parseHexToLong(longValHexRev, false)); + Assert.assertEquals(longVal, TbUtils.parseBigEndianHexToLong(longValHex)); + Assert.assertEquals(longVal, TbUtils.parseLittleEndianHexToLong(longValHexRev)); + } + + @Test + public void parseBytesToLong() { + byte[] longValByte = {64, -101, 4, -79, 12, -78, -107, -22}; + Assert.assertEquals(longVal, TbUtils.parseBytesToLong(longValByte, 0, 8)); + Bytes.reverse(longValByte); + Assert.assertEquals(longVal, TbUtils.parseBytesToLong(longValByte, 0, 8, false)); + + List longVaList = Bytes.asList(longValByte); + Assert.assertEquals(longVal, TbUtils.parseBytesToLong(longVaList, 0, 8, false)); + Assert.assertEquals(longValRev, TbUtils.parseBytesToLong(longVaList, 0, 8)); + } - // parseLong String.class, int.class -// parseLittleEndianHexToLong String.class - // parseBigEndianHexToLong String.class - // parseHexToLong String.class - // parseHexToLong String.class boolean.class - // parseBytesToLong List.class, int.class, int.class - // parseBytesToLong List.class, int.class, int.class, boolean.class - // parseBytesToLong byte[].class, int.class, int.class - // parseBytesToLong byte[].class, int.class, int.class, boolean.class - // parseLittleEndianHexToFloat String.class - // parseBigEndianHexToFloat String.class - // parseHexToFloat String.class - // parseHexToFloat String.class boolean.class - // parseBytesToFloat byte[].class, int.class, boolean.class - // parseBytesToFloat byte[].class, int.class - // parseBytesToFloat List.class, int.class, boolean.class - // parseBytesToFloat List.class, int.class - // toFixed float.class, int.class - // parseLittleEndianHexToDouble String.class - // parseBigEndianHexToDouble String.class - // parseHexToDouble String.class - // parseHexToDouble String.class boolean.class - // parseBytesToDouble byte[].class, int.class - // parseBytesToDouble byte[].class, int.class, boolean.class - // parseBytesToDouble List.class, int.class - // parseBytesToDouble List.class, int.class boolean.class - - - private static String keyToValue(String key, String extraSymbol) { - return key + "Value" + (extraSymbol == null ? "" : extraSymbol); + @Test + public void parsDouble() { + Assert.assertEquals(java.util.Optional.of(doubleVal).get(), TbUtils.parseDouble(doubleValStr)); + } + + @Test + public void toFixedDouble() { + double actualD = TbUtils.toFixed(doubleVal, 3); + Assert.assertEquals(-1, Double.compare(doubleVal, actualD)); + Assert.assertEquals(0, Double.compare(1729.173, actualD)); + } + + @Test + public void parseHexToDouble() { + Assert.assertEquals(0, Double.compare(doubleVal, TbUtils.parseHexToDouble(longValHex))); + Assert.assertEquals(0, Double.compare(doubleValRev, TbUtils.parseHexToDouble(longValHex, false))); + Assert.assertEquals(0, Double.compare(doubleVal, TbUtils.parseBigEndianHexToDouble(longValHex))); + Assert.assertEquals(0, Double.compare(doubleVal, TbUtils.parseLittleEndianHexToDouble(longValHexRev))); + } + + @Test + public void arseBytesToDouble() { + byte[] doubleValByte = {64, -101, 4, -79, 12, -78, -107, -22}; + Assert.assertEquals(0, Double.compare(doubleVal, TbUtils.parseBytesToDouble(doubleValByte, 0))); + Assert.assertEquals(0, Double.compare(doubleValRev, TbUtils.parseBytesToDouble(doubleValByte, 0, false))); + + List doubleVaList = Bytes.asList(doubleValByte); + Assert.assertEquals(0, Double.compare(doubleVal, TbUtils.parseBytesToDouble(doubleVaList, 0))); + Assert.assertEquals(0, Double.compare(doubleValRev, TbUtils.parseBytesToDouble(doubleVaList, 0, false))); } private static List toList(byte[] data) { @@ -287,5 +355,5 @@ public class TbUtilsTest { } return result; } - } + From d9c028f566ec695f6d9b975bd5c86abd1564af9d Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 19 Jun 2023 17:41:28 +0300 Subject: [PATCH 183/207] tbel: add Tests - long, float, double (syntax) --- .../test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java index e2f239f30e..b6d5395af8 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbUtilsTest.java @@ -338,7 +338,7 @@ public class TbUtilsTest { } @Test - public void arseBytesToDouble() { + public void parseBytesToDouble() { byte[] doubleValByte = {64, -101, 4, -79, 12, -78, -107, -22}; Assert.assertEquals(0, Double.compare(doubleVal, TbUtils.parseBytesToDouble(doubleValByte, 0))); Assert.assertEquals(0, Double.compare(doubleValRev, TbUtils.parseBytesToDouble(doubleValByte, 0, false))); From 1ec37d7685b3fe47e86a49d231a5cb26e5e64f82 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 20 Jun 2023 18:52:13 +0300 Subject: [PATCH 184/207] UI: Improve data keys config. Fix datasource type processing. --- ui-ngx/src/app/core/api/alias-controller.ts | 10 +- ui-ngx/src/app/core/services/utils.service.ts | 10 +- ui-ngx/src/app/core/ws/websocket.service.ts | 4 +- ...entities-table-basic-config.component.html | 1 + .../basic/common/data-key-row.component.html | 16 +++ .../basic/common/data-key-row.component.scss | 16 +++ .../basic/common/data-key-row.component.ts | 29 +++- .../common/data-keys-panel.component.html | 20 ++- .../common/data-keys-panel.component.scss | 17 +-- .../basic/common/data-keys-panel.component.ts | 7 + .../data-key-config-dialog.component.html | 7 +- .../data-key-config-dialog.component.ts | 38 ++++- .../config/data-key-config.component.html | 134 ++++++++++-------- .../config/data-key-config.component.scss | 23 +-- .../config/data-key-config.component.ts | 17 ++- ...entities-table-key-settings.component.html | 99 +++++++------ .../widget/lib/settings/widget-settings.scss | 4 + ui-ngx/src/app/shared/models/widget.models.ts | 5 + .../assets/locale/locale.constant-en_US.json | 2 + ui-ngx/src/styles.scss | 22 +++ 20 files changed, 305 insertions(+), 176 deletions(-) diff --git a/ui-ngx/src/app/core/api/alias-controller.ts b/ui-ngx/src/app/core/api/alias-controller.ts index be08d50d69..971f238d83 100644 --- a/ui-ngx/src/app/core/api/alias-controller.ts +++ b/ui-ngx/src/app/core/api/alias-controller.ts @@ -252,10 +252,9 @@ export class AliasController implements IAliasController { private resolveDatasource(datasource: Datasource, forceFilter = false): Observable { const newDatasource = deepClone(datasource); - if (newDatasource.type === DatasourceType.device) { - newDatasource.type = DatasourceType.entity; - } - if (newDatasource.type === DatasourceType.entity || newDatasource.type === DatasourceType.entityCount + if (newDatasource.type === DatasourceType.entity + || newDatasource.type === DatasourceType.device + || newDatasource.type === DatasourceType.entityCount || newDatasource.type === DatasourceType.alarmCount) { if (newDatasource.filterId) { newDatasource.keyFilters = this.getKeyFilters(newDatasource.filterId); @@ -263,7 +262,8 @@ export class AliasController implements IAliasController { if (newDatasource.type === DatasourceType.alarmCount) { newDatasource.alarmFilter = this.entityService.resolveAlarmFilter(newDatasource.alarmFilterConfig, false); } - if (newDatasource.deviceId) { + if (newDatasource.type === DatasourceType.device) { + newDatasource.type = DatasourceType.entity; newDatasource.entityFilter = singleEntityFilterFromDeviceId(newDatasource.deviceId); if (forceFilter) { return this.entityService.findSingleEntityInfoByEntityFilter(newDatasource.entityFilter, diff --git a/ui-ngx/src/app/core/services/utils.service.ts b/ui-ngx/src/app/core/services/utils.service.ts index f82c6c3072..09a0a08d58 100644 --- a/ui-ngx/src/app/core/services/utils.service.ts +++ b/ui-ngx/src/app/core/services/utils.service.ts @@ -282,13 +282,9 @@ export class UtilsService { public validateDatasources(datasources: Array): Array { datasources.forEach((datasource) => { - // @ts-ignore - if (datasource.type === 'device') { - datasource.type = DatasourceType.entity; - datasource.entityType = EntityType.DEVICE; - if (datasource.deviceId) { - datasource.entityId = datasource.deviceId; - } else if (datasource.deviceAliasId) { + if (datasource.type === DatasourceType.device) { + if (datasource.deviceAliasId) { + datasource.type = DatasourceType.entity; datasource.entityAliasId = datasource.deviceAliasId; } if (datasource.deviceName) { diff --git a/ui-ngx/src/app/core/ws/websocket.service.ts b/ui-ngx/src/app/core/ws/websocket.service.ts index 51545a6d54..2d2162267d 100644 --- a/ui-ngx/src/app/core/ws/websocket.service.ts +++ b/ui-ngx/src/app/core/ws/websocket.service.ts @@ -97,7 +97,9 @@ export abstract class WebsocketService implements WsServ this.dataStream.next(this.cmdWrapper.preparePublishCommands(MAX_PUBLISH_COMMANDS)); this.checkToClose(); } - this.tryOpenSocket(); + if (this.subscribersCount > 0) { + this.tryOpenSocket(); + } } private checkToClose() { diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html index ee76bdf472..65b08c6798 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html @@ -28,6 +28,7 @@
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss index 5b3d4f1a80..8bb8d720f3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.scss @@ -51,3 +51,19 @@ align-items: center; } } + +.tb-data-keys-table-row-buttons { + display: flex; + flex-direction: row; + button.mat-mdc-icon-button.mat-mdc-button-base { + padding: 7px; + width: 38px; + height: 38px; + .mat-icon { + color: rgba(0, 0, 0, 0.38); + } + &.tb-hidden { + visibility: hidden; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts index d434ef74e3..750abd3a8a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts @@ -18,10 +18,12 @@ import { ChangeDetectorRef, Component, ElementRef, + EventEmitter, forwardRef, Input, OnChanges, OnInit, + Output, SimpleChanges, ViewChild, ViewEncapsulation @@ -37,7 +39,14 @@ import { } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; -import { DataKey, DatasourceType, JsonSettingsSchema, Widget, widgetType } from '@shared/models/widget.models'; +import { + DataKey, + DataKeyConfigMode, + DatasourceType, + JsonSettingsSchema, + Widget, + widgetType +} from '@shared/models/widget.models'; import { DataKeysPanelComponent } from '@home/components/widget/config/basic/common/data-keys-panel.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { AggregationType } from '@shared/models/time/time.models'; @@ -104,6 +113,9 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan @Input() deviceId: string; + @Output() + keyRemoved = new EventEmitter(); + keyFormControl: UntypedFormControl; keyRowFormGroup: UntypedFormGroup; @@ -169,6 +181,18 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan return this.modelValue.type && ![ DataKeyType.alarm, DataKeyType.entityField, DataKeyType.count ].includes(this.modelValue.type); } + get keySettingsTitle(): string { + return this.dataKeysPanelComponent.keySettingsTitle; + } + + get removeKeyTitle(): string { + return this.dataKeysPanelComponent.removeKeyTitle; + } + + get dragEnabled(): boolean { + return this.dataKeysPanelComponent.dragEnabled; + } + private propagateChange = (_val: any) => {}; constructor(private fb: UntypedFormBuilder, @@ -291,13 +315,14 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan } } - editKey() { + editKey(advanced = false) { this.dialog.open(DataKeyConfigDialogComponent, { disableClose: true, panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], data: { dataKey: deepClone(this.modelValue), + dataKeyConfigMode: advanced ? DataKeyConfigMode.advanced : DataKeyConfigMode.general, dataKeySettingsSchema: this.datakeySettingsSchema, dataKeySettingsDirective: this.dataKeySettingsDirective, dashboard: this.dashboard, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html index 754f0052c9..6960e57ee1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html @@ -26,27 +26,25 @@
widget-config.decimals-short
-
-
+
+ [entityAliasId]="entityAliasId" + (keyRemoved)="removeKey($index)">
- - -
{{alarmSeverityTranslations.get(notification.info.alarmSeverity) | translate}} diff --git a/ui-ngx/src/app/shared/components/notification/notification.component.ts b/ui-ngx/src/app/shared/components/notification/notification.component.ts index ad543c43c1..6e1ff508a7 100644 --- a/ui-ngx/src/app/shared/components/notification/notification.component.ts +++ b/ui-ngx/src/app/shared/components/notification/notification.component.ts @@ -139,7 +139,7 @@ export class NotificationComponent implements OnInit { } notificationColor(): string { - if (this.notification.type === NotificationType.ALARM) { + if (this.notification.type === NotificationType.ALARM && !this.notification.info.cleared) { return AlarmSeverityNotificationColors.get(this.notification.info.alarmSeverity); } return 'transparent'; diff --git a/ui-ngx/src/app/shared/models/notification.models.ts b/ui-ngx/src/app/shared/models/notification.models.ts index 2cef7c6cc2..4d8a9cffcd 100644 --- a/ui-ngx/src/app/shared/models/notification.models.ts +++ b/ui-ngx/src/app/shared/models/notification.models.ts @@ -48,6 +48,8 @@ export interface NotificationInfo { alarmStatus?: AlarmStatus; alarmType?: string; stateEntityId?: EntityId; + acknowledged?: boolean; + cleared?: boolean; } export interface NotificationRequest extends Omit, 'label'> { From 7ff353a4d9758f40314f7e991ef87f1f94dcac34 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 27 Jun 2023 17:54:02 +0300 Subject: [PATCH 204/207] swagger_device_controller: fix bug example request - X509, MQTT_BASIC --- .../controller/ControllerConstants.java | 81 ++++++++++++++++++- .../server/controller/DeviceController.java | 13 ++- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index 6fe53516ed..bbd2773e6b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java @@ -15,6 +15,16 @@ */ package org.thingsboard.server.controller; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.thingsboard.server.common.msg.EncryptionUtil.certTrimNewLinesForChainInDeviceProfile; + public class ControllerConstants { protected static final String NEW_LINE = "\n\n"; @@ -236,7 +246,59 @@ public class ControllerConstants { " }\n" + "}"; - protected static final String CREDENTIALS_VALUE_LVM2M_RPK_DESCRIPTION = + protected static final String[] getCertificateValue() { + String filePath = "src/test/resources/provision/x509ChainProvisionTest.pem"; + try { + String certificateChain = Files.readString(Paths.get(filePath)); + certificateChain = certTrimNewLinesForChainInDeviceProfile(certificateChain); + return fetchLeafCertificateFromChain(certificateChain); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + protected static final String certificateValue = "\"-----BEGIN CERTIFICATE----- " + + "MIICMTCCAdegAwIBAgIUI9dBuwN6pTtK6uZ03rkiCwV4wEYwCgYIKoZIzj0EAwIwbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTYxN1oXDTI0MDMyODE0NTYxN1owbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9Zo791qKQiGNBm11r4ZGxh+w+ossZL3xc46ufq5QckQHP7zkD2XDAcmP5GvdkM1sBFN9AWaCkQfNnWmfERsOOKNTMFEwHQYDVR0OBBYEFFFc5uyCyglQoZiKhzXzMcQ3BKORMB8GA1UdIwQYMBaAFFFc5uyCyglQoZiKhzXzMcQ3BKORMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhANbA9CuhoOifZMMmqkpuld+65CR+ItKdXeRAhLMZuccuAiB0FSQB34zMutXrZj1g8Gl5OkE7YryFHbei1z0SveHR8g== " + + "-----END CERTIFICATE-----\""; + + protected static final String certificateId = "\"84f5911765abba1f96bf4165604e9e90338fc6214081a8e623b6ff9669aedb27\""; + + protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_X509_CERTIFICATE_PARAM_DESCRIPTION = + "{\n" + + " \"device\": {\n" + + " \"name\":\"Name_DeviceWithCredantial_X509_Certificate\",\n" + + " \"label\":\"Label_DeviceWithCredantial_X509_Certificate\",\n" + + " \"deviceProfileId\":{\n" + + " \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n" + + " \"entityType\":\"DEVICE_PROFILE\"\n" + + " }\n" + + " },\n" + + " \"credentials\": {\n" + + " \"credentialsType\": \"X509_CERTIFICATE\",\n" + + " \"credentialsId\": " + certificateId + ",\n" + + " \"credentialsValue\": " + certificateValue + "\n" + + " }\n" + + "}"; + + protected static final String MQTT_BASIC_VALUE = "\"{\\\"clientId\\\":\\\"5euh5nzm34bjjh1efmlt\\\",\\\"userName\\\":\\\"onasd1lgwasmjl7v2v7h\\\",\\\"password\\\":\\\"b9xtm4ny8kt9zewaga5o\\\"}\""; + + protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_MQTT_BASIC_PARAM_DESCRIPTION = + "{\n" + + " \"device\": {\n" + + " \"name\":\"Name_DeviceWithCredantial_MQTT_Basic\",\n" + + " \"label\":\"Label_DeviceWithCredantial_MQTT_Basic\",\n" + + " \"deviceProfileId\":{\n" + + " \"id\":\"9d9588c0-06c9-11ee-b618-19be30fdeb60\",\n" + + " \"entityType\":\"DEVICE_PROFILE\"\n" + + " }\n" + + " },\n" + + " \"credentials\": {\n" + + " \"credentialsType\": \"MQTT_BASIC\",\n" + + " \"credentialsValue\": " + MQTT_BASIC_VALUE + "\n" + + " }\n" + + "}"; + + protected static final String CREDENTIALS_VALUE_LVM2M_RPK_DESCRIPTION = " \"{" + "\\\"client\\\":{ " + "\\\"endpoint\\\":\\\"LwRpk00000000\\\", " + @@ -279,6 +341,12 @@ public class ControllerConstants { protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DEFAULT_DESCRIPTION_MARKDOWN = MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_ACCESS_TOKEN_DEFAULT_PARAM_DESCRIPTION + MARKDOWN_CODE_BLOCK_END; + protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_X509_CERTIFICATE_DESCRIPTION_MARKDOWN = + MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_X509_CERTIFICATE_PARAM_DESCRIPTION + MARKDOWN_CODE_BLOCK_END; + + protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_MQTT_BASIC_DESCRIPTION_MARKDOWN = + MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_MQTT_BASIC_PARAM_DESCRIPTION + MARKDOWN_CODE_BLOCK_END; + protected static final String DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION_MARKDOWN = MARKDOWN_CODE_BLOCK_START + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION + MARKDOWN_CODE_BLOCK_END; @@ -1594,4 +1662,15 @@ public class ControllerConstants { MARKDOWN_CODE_BLOCK_START + "[{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}}]" + MARKDOWN_CODE_BLOCK_END ; + + private static String[] fetchLeafCertificateFromChain(String value) { + List chain = new ArrayList<>(); + String regex = "-----BEGIN CERTIFICATE-----\\s*.*?\\s*-----END CERTIFICATE-----"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(value); + while (matcher.find()) { + chain.add(matcher.group(0)); + } + return chain.toArray(new String[0]); + } } diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 842e47756d..f033b2758f 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -96,6 +96,8 @@ import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TYPE_ import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DEFAULT_DESCRIPTION_MARKDOWN; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DESCRIPTION_MARKDOWN; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION_MARKDOWN; +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_MQTT_BASIC_DESCRIPTION_MARKDOWN; +import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_X509_CERTIFICATE_DESCRIPTION_MARKDOWN; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION; @@ -185,13 +187,18 @@ public class DeviceController extends BaseController { @ApiOperation(value = "Create Device (saveDevice) with credentials ", notes = "Create or update the Device. When creating device, platform generates Device Id as " + UUID_WIKI_LINK + "Requires to provide the Device Credentials object as well as an existing device profile ID or use \"default\".\n" + - "Note: LwM2M device - only existing device profile ID (Transport configuration -> Transport type: \"LWM2M\".\n\n" + "You may find the example of device with different type of credentials below: \n\n" + - "- Credentials type: \"Access token\" with Device profile ID below: \n\n" + + "- Credentials type: \"Access token\" with device profile ID below: \n\n" + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DESCRIPTION_MARKDOWN + "\n\n" + - "- Credentials type: \"Access token\" with Device profile default below: \n\n" + + "- Credentials type: \"Access token\" with device profile default below: \n\n" + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_ACCESS_TOKEN_DEFAULT_DESCRIPTION_MARKDOWN + "\n\n" + + "- Credentials type: \"X509\" with device profile ID below: \n\n" + + "Note: credentialsId - format Sha3Hash, certificateValue - format PEM (with \"--BEGIN CERTIFICATE----\" and -\"----END CERTIFICATE-\").\n\n" + + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_X509_CERTIFICATE_DESCRIPTION_MARKDOWN + "\n\n" + + "- Credentials type: \"MQTT_BASIC\" with device profile ID below: \n\n" + + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_MQTT_BASIC_DESCRIPTION_MARKDOWN + "\n\n" + "- You may find the example of LwM2M device and RPK credentials below: \n\n" + + "Note: LwM2M device - only existing device profile ID (Transport configuration -> Transport type: \"LWM2M\".\n\n" + DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_LVM2M_RPK_DESCRIPTION_MARKDOWN + "\n\n" + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Device entity. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) From 1cb74577d510bf971c57507c24156fa618e5d213 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 27 Jun 2023 18:09:21 +0300 Subject: [PATCH 205/207] swagger_device_controller: refactoring fix bug example request - X509, MQTT_BASIC --- .../controller/ControllerConstants.java | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index bbd2773e6b..7701a19f02 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java @@ -15,16 +15,6 @@ */ package org.thingsboard.server.controller; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static org.thingsboard.server.common.msg.EncryptionUtil.certTrimNewLinesForChainInDeviceProfile; - public class ControllerConstants { protected static final String NEW_LINE = "\n\n"; @@ -246,17 +236,6 @@ public class ControllerConstants { " }\n" + "}"; - protected static final String[] getCertificateValue() { - String filePath = "src/test/resources/provision/x509ChainProvisionTest.pem"; - try { - String certificateChain = Files.readString(Paths.get(filePath)); - certificateChain = certTrimNewLinesForChainInDeviceProfile(certificateChain); - return fetchLeafCertificateFromChain(certificateChain); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - protected static final String certificateValue = "\"-----BEGIN CERTIFICATE----- " + "MIICMTCCAdegAwIBAgIUI9dBuwN6pTtK6uZ03rkiCwV4wEYwCgYIKoZIzj0EAwIwbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTYxN1oXDTI0MDMyODE0NTYxN1owbjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGluZ3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVByb3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9Zo791qKQiGNBm11r4ZGxh+w+ossZL3xc46ufq5QckQHP7zkD2XDAcmP5GvdkM1sBFN9AWaCkQfNnWmfERsOOKNTMFEwHQYDVR0OBBYEFFFc5uyCyglQoZiKhzXzMcQ3BKORMB8GA1UdIwQYMBaAFFFc5uyCyglQoZiKhzXzMcQ3BKORMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhANbA9CuhoOifZMMmqkpuld+65CR+ItKdXeRAhLMZuccuAiB0FSQB34zMutXrZj1g8Gl5OkE7YryFHbei1z0SveHR8g== " + "-----END CERTIFICATE-----\""; @@ -1662,15 +1641,4 @@ public class ControllerConstants { MARKDOWN_CODE_BLOCK_START + "[{\"ts\":1634712287000,\"values\":{\"temperature\":26, \"humidity\":87}}, {\"ts\":1634712588000,\"values\":{\"temperature\":25, \"humidity\":88}}]" + MARKDOWN_CODE_BLOCK_END ; - - private static String[] fetchLeafCertificateFromChain(String value) { - List chain = new ArrayList<>(); - String regex = "-----BEGIN CERTIFICATE-----\\s*.*?\\s*-----END CERTIFICATE-----"; - Pattern pattern = Pattern.compile(regex); - Matcher matcher = pattern.matcher(value); - while (matcher.find()) { - chain.add(matcher.group(0)); - } - return chain.toArray(new String[0]); - } } From 987d41f329cd941dc43e6c917bcd10e36bf95acc Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 27 Jun 2023 18:17:15 +0300 Subject: [PATCH 206/207] UI: Timeseries table basic config --- .../json/system/widget_bundles/cards.json | 4 +- .../dashboard-page.component.ts | 4 +- .../basic/basic-widget-config.module.ts | 8 +- .../entities-table-basic-config.component.ts | 9 +- ...meseries-table-basic-config.component.html | 94 +++++++++ ...timeseries-table-basic-config.component.ts | 181 ++++++++++++++++++ .../basic/common/data-key-row.component.html | 6 + .../basic/common/data-key-row.component.scss | 4 + .../basic/common/data-key-row.component.ts | 38 +++- .../common/data-keys-panel.component.html | 2 + .../common/data-keys-panel.component.scss | 3 + .../basic/common/data-keys-panel.component.ts | 29 ++- ...meseries-table-key-settings.component.html | 87 +++++---- ...s-table-latest-key-settings.component.html | 104 +++++----- ...eries-table-widget-settings.component.html | 109 +++++------ .../shared/components/tb-error.component.ts | 7 +- .../assets/locale/locale.constant-en_US.json | 8 +- 17 files changed, 538 insertions(+), 159 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.ts diff --git a/application/src/main/data/json/system/widget_bundles/cards.json b/application/src/main/data/json/system/widget_bundles/cards.json index 9ab33665e6..473d3d215b 100644 --- a/application/src/main/data/json/system/widget_bundles/cards.json +++ b/application/src/main/data/json/system/widget_bundles/cards.json @@ -64,7 +64,9 @@ "settingsDirective": "tb-timeseries-table-widget-settings", "dataKeySettingsDirective": "tb-timeseries-table-key-settings", "latestDataKeySettingsDirective": "tb-timeseries-table-latest-key-settings", - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature °C\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = (value + 60)/120 * 100;\\n var color = tinycolor.mix('blue', 'red', percent);\\n color.setAlpha(.5);\\n return {\\n paddingLeft: '20px',\\n color: '#ffffff',\\n background: color.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity, %\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = value;\\n var backgroundColor = tinycolor('blue');\\n backgroundColor.setAlpha(value/100);\\n var color = 'blue';\\n if (value > 50) {\\n color = 'white';\\n }\\n \\n return {\\n paddingLeft: '20px',\\n color: color,\\n background: backgroundColor.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 5) {\\n\\tvalue = 5;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}],\"latestDataKeys\":null}],\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"showTimestamp\":true,\"displayPagination\":true,\"defaultPageSize\":10},\"title\":\"Timeseries table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"displayTimewindow\":true}" + "hasBasicMode": true, + "basicModeDirective": "tb-timeseries-table-basic-config", + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"entityAliasId\":null,\"filterId\":null,\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Temperature °C\",\"color\":\"#2196f3\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = (value + 60)/120 * 100;\\n var color = tinycolor.mix('blue', 'red', percent);\\n color.setAlpha(.5);\\n return {\\n paddingLeft: '20px',\\n color: '#ffffff',\\n background: color.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -60) {\\n\\tvalue = -60;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity, %\",\"color\":\"#ffc107\",\"settings\":{\"useCellStyleFunction\":true,\"cellStyleFunction\":\"if (value) {\\n var percent = value;\\n var backgroundColor = tinycolor('blue');\\n backgroundColor.setAlpha(value/100);\\n var color = 'blue';\\n if (value > 50) {\\n color = 'white';\\n }\\n \\n return {\\n paddingLeft: '20px',\\n color: color,\\n background: backgroundColor.toRgbString(),\\n fontSize: '18px'\\n };\\n} else {\\n return {};\\n}\",\"useCellContentFunction\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 20 - 10;\\nvar multiplier = Math.pow(10, 1 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 5) {\\n\\tvalue = 5;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value;\"}],\"latestDataKeys\":null}],\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"showTimestamp\":true,\"displayPagination\":true,\"defaultPageSize\":10},\"title\":\"Timeseries table\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"widgetStyle\":{},\"actions\":{},\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"displayTimewindow\":true,\"configMode\":\"basic\"}" } }, { diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts index d6518d0007..39940546c2 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts @@ -1152,7 +1152,9 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC this.widgetComponentService.getWidgetInfo(widget.bundleAlias, widget.typeAlias, widget.isSystemType).subscribe( (widgetTypeInfo) => { const config: WidgetConfig = this.dashboardUtils.widgetConfigFromWidgetType(widgetTypeInfo); - config.title = 'New ' + widgetTypeInfo.widgetName; + if (!config.title) { + config.title = 'New ' + widgetTypeInfo.widgetName; + } let newWidget: Widget = { isSystemType: widget.isSystemType, bundleAlias: widget.bundleAlias, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index 73ebfb37c7..f292198f1e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -30,12 +30,16 @@ import { } from '@home/components/widget/config/basic/cards/entities-table-basic-config.component'; import { DataKeysPanelComponent } from '@home/components/widget/config/basic/common/data-keys-panel.component'; import { DataKeyRowComponent } from '@home/components/widget/config/basic/common/data-key-row.component'; +import { + TimeseriesTableBasicConfigComponent +} from '@home/components/widget/config/basic/cards/timeseries-table-basic-config.component'; @NgModule({ declarations: [ WidgetActionsPanelComponent, SimpleCardBasicConfigComponent, EntitiesTableBasicConfigComponent, + TimeseriesTableBasicConfigComponent, DataKeyRowComponent, DataKeysPanelComponent ], @@ -48,6 +52,7 @@ import { DataKeyRowComponent } from '@home/components/widget/config/basic/common WidgetActionsPanelComponent, SimpleCardBasicConfigComponent, EntitiesTableBasicConfigComponent, + TimeseriesTableBasicConfigComponent, DataKeyRowComponent, DataKeysPanelComponent ] @@ -57,5 +62,6 @@ export class BasicWidgetConfigModule { export const basicWidgetConfigComponentsMap: {[key: string]: Type} = { 'tb-simple-card-basic-config': SimpleCardBasicConfigComponent, - 'tb-entities-table-basic-config': EntitiesTableBasicConfigComponent + 'tb-entities-table-basic-config': EntitiesTableBasicConfigComponent, + 'tb-timeseries-table-basic-config': TimeseriesTableBasicConfigComponent }; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts index f7211d6a54..b0897f05bc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts @@ -28,6 +28,7 @@ import { } from '@shared/models/widget.models'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { isUndefined } from '@core/utils'; @Component({ selector: 'tb-entities-table-basic-config', @@ -75,7 +76,7 @@ export class EntitiesTableBasicConfigComponent extends BasicWidgetConfigComponen this.entitiesTableWidgetConfigForm = this.fb.group({ timewindowConfig: [{ useDashboardTimewindow: configData.config.useDashboardTimewindow, - displayTimewindow: configData.config.useDashboardTimewindow, + displayTimewindow: configData.config.displayTimewindow, timewindow: configData.config.timewindow }, []], datasources: [configData.config.datasources, []], @@ -155,13 +156,13 @@ export class EntitiesTableBasicConfigComponent extends BasicWidgetConfigComponen private getCardButtons(config: WidgetConfig): string[] { const buttons: string[] = []; - if (config.settings?.enableSearch) { + if (isUndefined(config.settings?.enableSearch) || config.settings?.enableSearch) { buttons.push('search'); } - if (config.settings?.enableSelectColumnDisplay) { + if (isUndefined(config.settings?.enableSelectColumnDisplay) || config.settings?.enableSelectColumnDisplay) { buttons.push('columnsToDisplay'); } - if (config.enableFullscreen) { + if (isUndefined(config.enableFullscreen) || config.enableFullscreen) { buttons.push('fullscreen'); } return buttons; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html new file mode 100644 index 0000000000..158b734a4a --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html @@ -0,0 +1,94 @@ + + + + + + + + +
+
widget-config.appearance
+
+ + {{ 'widget-config.card-title' | translate }} + + + + +
+
+ + {{ 'widget-config.card-icon' | translate }} + +
+ + + + + +
+
+
+
widgets.table.show-card-buttons
+ + {{ 'action.search' | translate }} + {{ 'widgets.table.columns-to-display' | translate }} + {{ 'fullscreen.fullscreen' | translate }} + +
+
+
{{ 'widget-config.text-color' | translate }}
+
+ + + +
+
+
+
{{ 'widget-config.background-color' | translate }}
+
+ + + +
+
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.ts new file mode 100644 index 0000000000..e650f9a344 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.ts @@ -0,0 +1,181 @@ +/// +/// Copyright © 2016-2023 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { + DataKey, + Datasource, + datasourcesHasAggregation, + datasourcesHasOnlyComparisonAggregation, WidgetConfig +} from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { deepClone, isUndefined } from '@core/utils'; + +@Component({ + selector: 'tb-timeseries-table-basic-config', + templateUrl: './timeseries-table-basic-config.component.html', + styleUrls: ['../basic-config.scss'] +}) +export class TimeseriesTableBasicConfigComponent extends BasicWidgetConfigComponent { + + public get datasource(): Datasource { + const datasources: Datasource[] = this.timeseriesTableWidgetConfigForm.get('datasources').value; + if (datasources && datasources.length) { + return datasources[0]; + } else { + return null; + } + } + + timeseriesTableWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, + private fb: UntypedFormBuilder) { + super(store, widgetConfigComponent); + } + + protected configForm(): UntypedFormGroup { + return this.timeseriesTableWidgetConfigForm; + } + + protected setupDefaults(configData: WidgetConfigComponentData) { + this.setupDefaultDatasource(configData, + [{ name: 'temperature', label: 'Temperature', type: DataKeyType.timeseries, units: '°C', decimals: 0 }]); + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + this.timeseriesTableWidgetConfigForm = this.fb.group({ + timewindowConfig: [{ + useDashboardTimewindow: configData.config.useDashboardTimewindow, + displayTimewindow: configData.config.displayTimewindow, + timewindow: configData.config.timewindow + }, []], + datasources: [configData.config.datasources, []], + columns: [this.getColumns(configData.config.datasources), []], + showTitle: [configData.config.showTitle, []], + title: [configData.config.title, []], + showTitleIcon: [configData.config.showTitleIcon, []], + titleIcon: [configData.config.titleIcon, []], + iconColor: [configData.config.iconColor, []], + cardButtons: [this.getCardButtons(configData.config), []], + color: [configData.config.color, []], + backgroundColor: [configData.config.backgroundColor, []], + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + this.widgetConfig.config.useDashboardTimewindow = config.timewindowConfig.useDashboardTimewindow; + this.widgetConfig.config.displayTimewindow = config.timewindowConfig.displayTimewindow; + this.widgetConfig.config.timewindow = config.timewindowConfig.timewindow; + this.widgetConfig.config.datasources = config.datasources; + this.setColumns(config.columns, this.widgetConfig.config.datasources); + this.widgetConfig.config.actions = config.actions; + this.widgetConfig.config.showTitle = config.showTitle; + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + this.widgetConfig.config.settings.entitiesTitle = config.title; + this.widgetConfig.config.showTitleIcon = config.showTitleIcon; + this.widgetConfig.config.titleIcon = config.titleIcon; + this.widgetConfig.config.iconColor = config.iconColor; + this.setCardButtons(config.cardButtons, this.widgetConfig.config); + this.widgetConfig.config.color = config.color; + this.widgetConfig.config.backgroundColor = config.backgroundColor; + return this.widgetConfig; + } + + protected validatorTriggers(): string[] { + return ['showTitle', 'showTitleIcon']; + } + + protected updateValidators(emitEvent: boolean, trigger?: string) { + const showTitle: boolean = this.timeseriesTableWidgetConfigForm.get('showTitle').value; + const showTitleIcon: boolean = this.timeseriesTableWidgetConfigForm.get('showTitleIcon').value; + if (showTitle) { + this.timeseriesTableWidgetConfigForm.get('title').enable(); + this.timeseriesTableWidgetConfigForm.get('showTitleIcon').enable({emitEvent: false}); + if (showTitleIcon) { + this.timeseriesTableWidgetConfigForm.get('titleIcon').enable(); + this.timeseriesTableWidgetConfigForm.get('iconColor').enable(); + } else { + this.timeseriesTableWidgetConfigForm.get('titleIcon').disable(); + this.timeseriesTableWidgetConfigForm.get('iconColor').disable(); + } + } else { + this.timeseriesTableWidgetConfigForm.get('title').disable(); + this.timeseriesTableWidgetConfigForm.get('showTitleIcon').disable({emitEvent: false}); + this.timeseriesTableWidgetConfigForm.get('titleIcon').disable(); + this.timeseriesTableWidgetConfigForm.get('iconColor').disable(); + } + this.timeseriesTableWidgetConfigForm.get('title').updateValueAndValidity({emitEvent}); + this.timeseriesTableWidgetConfigForm.get('showTitleIcon').updateValueAndValidity({emitEvent: false}); + this.timeseriesTableWidgetConfigForm.get('titleIcon').updateValueAndValidity({emitEvent}); + this.timeseriesTableWidgetConfigForm.get('iconColor').updateValueAndValidity({emitEvent}); + } + + private getColumns(datasources?: Datasource[]): DataKey[] { + if (datasources && datasources.length) { + const dataKeys = deepClone(datasources[0].dataKeys) || []; + dataKeys.forEach(k => { + (k as any).latest = false; + }); + const latestDataKeys = deepClone(datasources[0].latestDataKeys) || []; + latestDataKeys.forEach(k => { + (k as any).latest = true; + }); + return dataKeys.concat(latestDataKeys); + } + return []; + } + + private setColumns(columns: DataKey[], datasources?: Datasource[]) { + if (datasources && datasources.length) { + const dataKeys = deepClone(columns.filter(c => !(c as any).latest)); + dataKeys.forEach(k => delete (k as any).latest); + const latestDataKeys = deepClone(columns.filter(c => (c as any).latest)); + latestDataKeys.forEach(k => delete (k as any).latest); + datasources[0].dataKeys = dataKeys; + datasources[0].latestDataKeys = latestDataKeys; + } + } + + private getCardButtons(config: WidgetConfig): string[] { + const buttons: string[] = []; + if (isUndefined(config.settings?.enableSearch) || config.settings?.enableSearch) { + buttons.push('search'); + } + if (isUndefined(config.settings?.enableSelectColumnDisplay) || config.settings?.enableSelectColumnDisplay) { + buttons.push('columnsToDisplay'); + } + if (isUndefined(config.enableFullscreen) || config.enableFullscreen) { + buttons.push('fullscreen'); + } + return buttons; + } + + private setCardButtons(buttons: string[], config: WidgetConfig) { + config.settings.enableSearch = buttons.includes('search'); + config.settings.enableSelectColumnDisplay = buttons.includes('columnsToDisplay'); + config.enableFullscreen = buttons.includes('fullscreen'); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html index ee7adc3df2..7bfa1e59b1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html @@ -16,6 +16,12 @@ -->
+ + + {{ 'datakey.timeseries' | translate }} + {{ 'datakey.latest' | translate }} + + {}; constructor(private fb: UntypedFormBuilder, @@ -212,6 +229,12 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan units: [null, []], decimals: [null, []], }); + if (this.hasAdditionalLatestDataKeys) { + this.keyRowFormGroup.addControl('latest', this.fb.control(false)); + this.keyRowFormGroup.valueChanges.subscribe( + () => this.clearKeySearchCache() + ); + } this.keyRowFormGroup.valueChanges.subscribe( () => this.updateModel() ); @@ -286,6 +309,11 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan decimals: value?.decimals }, {emitEvent: false} ); + if (this.hasAdditionalLatestDataKeys) { + this.keyRowFormGroup.patchValue({ + latest: (value as any)?.latest + }, {emitEvent: false}); + } this.cd.markForCheck(); } @@ -323,8 +351,8 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan data: { dataKey: deepClone(this.modelValue), dataKeyConfigMode: advanced ? DataKeyConfigMode.advanced : DataKeyConfigMode.general, - dataKeySettingsSchema: this.datakeySettingsSchema, - dataKeySettingsDirective: this.dataKeySettingsDirective, + dataKeySettingsSchema: this.isLatestDataKeys ? this.latestDataKeySettingsSchema : this.dataKeySettingsSchema, + dataKeySettingsDirective: this.isLatestDataKeys ? this.latestDataKeySettingsDirective : this.dataKeySettingsDirective, dashboard: this.dashboard, aliasController: this.aliasController, widget: this.widget, @@ -399,7 +427,7 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan } else if (this.datasourceType === DatasourceType.entity && this.entityAliasId || this.datasourceType === DatasourceType.device && this.deviceId) { const dataKeyTypes = [DataKeyType.timeseries]; - if (this.widgetType === widgetType.latest || this.widgetType === widgetType.alarm) { + if (this.isLatestDataKeys || this.widgetType === widgetType.latest || this.widgetType === widgetType.alarm) { dataKeyTypes.push(DataKeyType.attribute); dataKeyTypes.push(DataKeyType.entityField); if (this.widgetType === widgetType.alarm) { @@ -428,7 +456,7 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan } private addKeyFromChipValue(chip: DataKey) { - this.modelValue = this.callbacks.generateDataKey(chip.name, chip.type, this.datakeySettingsSchema); + this.modelValue = this.callbacks.generateDataKey(chip.name, chip.type, this.dataKeySettingsSchema); if (!this.keyRowFormGroup.get('label').value) { this.keyRowFormGroup.get('label').patchValue(this.modelValue.label, {emitEvent: false}); } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html index 6960e57ee1..23aab3c720 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html @@ -19,6 +19,7 @@
{{ panelTitle }}
+
datakey.source
datakey.key
datakey.label
datakey.color
@@ -52,6 +53,7 @@
+
+
- - - + + {{ 'widgets.table.use-cell-content-function' | translate }} - + widget-config.advanced-settings @@ -65,30 +95,5 @@ - - - widgets.table.default-column-visibility - - - {{ 'widgets.table.column-visibility-visible' | translate }} - - - {{ 'widgets.table.column-visibility-hidden' | translate }} - - - {{ 'widgets.table.column-visibility-hidden-mobile' | translate }} - - - - - widgets.table.column-selection-to-display - - - {{ 'widgets.table.column-selection-to-display-enabled' | translate }} - - - {{ 'widgets.table.column-selection-to-display-disabled' | translate }} - - - - +
+ diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html index 8fb1629b13..dcdc8c2904 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html @@ -15,25 +15,58 @@ limitations under the License. --> -
- - {{ 'widgets.table.show-latest-data-column' | translate }} - - - widgets.table.latest-data-column-order - - -
- widgets.table.cell-style + +
+
widgets.table.column-settings
+ + {{ 'widgets.table.show-latest-data-column' | translate }} + +
+
widgets.table.latest-data-column-order
+ + + +
+
+
{{ 'widgets.table.default-column-visibility' | translate }}
+ + + + {{ 'widgets.table.column-visibility-visible' | translate }} + + + {{ 'widgets.table.column-visibility-hidden' | translate }} + + + {{ 'widgets.table.column-visibility-hidden-mobile' | translate }} + + + +
+
+
{{ 'widgets.table.column-selection-to-display' | translate }}
+ + + + {{ 'widgets.table.column-selection-to-display-enabled' | translate }} + + + {{ 'widgets.table.column-selection-to-display-disabled' | translate }} + + + +
+
+
- - - + + {{ 'widgets.table.use-cell-style-function' | translate }} - + widget-config.advanced-settings @@ -47,18 +80,17 @@ -
-
- widgets.table.cell-content +
+
- - - + + {{ 'widgets.table.use-cell-content-function' | translate }} - + widget-config.advanced-settings @@ -72,30 +104,6 @@ - - - widgets.table.default-column-visibility - - - {{ 'widgets.table.column-visibility-visible' | translate }} - - - {{ 'widgets.table.column-visibility-hidden' | translate }} - - - {{ 'widgets.table.column-visibility-hidden-mobile' | translate }} - - - - - widgets.table.column-selection-to-display - - - {{ 'widgets.table.column-selection-to-display-enabled' | translate }} - - - {{ 'widgets.table.column-selection-to-display-disabled' | translate }} - - - - +
+ + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html index ed4428fe45..b2743142a4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html @@ -15,28 +15,31 @@ limitations under the License. --> -
-
- widgets.table.common-table-settings -
-
- - {{ 'widgets.table.enable-search' | translate }} - - - {{ 'widgets.table.enable-select-column-display' | translate }} - -
-
- - {{ 'widgets.table.enable-sticky-header' | translate }} - - - {{ 'widgets.table.enable-sticky-action' | translate }} - -
-
- + +
+
widgets.table.table-header
+ + {{ 'widgets.table.enable-sticky-header' | translate }} + + + {{ 'widgets.table.enable-search' | translate }} + + + {{ 'widgets.table.enable-select-column-display' | translate }} + +
+
+
widgets.table.columns
+ + {{ 'widgets.table.display-timestamp' | translate }} + + + {{ 'widgets.table.display-milliseconds' | translate }} + + + {{ 'widgets.table.enable-sticky-action' | translate }} + + widgets.table.hidden-cell-button-display-mode @@ -47,41 +50,39 @@ -
- - {{ 'widgets.table.display-timestamp' | translate }} - - - {{ 'widgets.table.display-milliseconds' | translate }} - -
- - {{ 'widgets.table.display-pagination' | translate }} - - - widgets.table.default-page-size - - -
- - {{ 'widgets.table.use-entity-label-tab-name' | translate }} - - - {{ 'widgets.table.hide-empty-lines' | translate }} - -
-
-
- widgets.table.row-style +
+
+
widgets.table.pagination
+ + {{ 'widgets.table.display-pagination' | translate }} + +
+
widgets.table.default-page-size
+ + + +
+
+
+
widgets.table.table-tabs
+ + {{ 'widgets.table.use-entity-label-tab-name' | translate }} + +
+
+
widgets.table.rows
+ + {{ 'widgets.table.hide-empty-lines' | translate }} + - - - + + {{ 'widgets.table.use-row-style-function' | translate }} - + widget-config.advanced-settings @@ -95,5 +96,5 @@ - - +
+ diff --git a/ui-ngx/src/app/shared/components/tb-error.component.ts b/ui-ngx/src/app/shared/components/tb-error.component.ts index 08959e2949..5ddd2d7896 100644 --- a/ui-ngx/src/app/shared/components/tb-error.component.ts +++ b/ui-ngx/src/app/shared/components/tb-error.component.ts @@ -16,11 +16,12 @@ import { Component, Input } from '@angular/core'; import { animate, state, style, transition, trigger } from '@angular/animations'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-error', template: ` -
+
{{message}} @@ -51,6 +52,10 @@ export class TbErrorComponent { state: any; message; + @Input() + @coerceBoolean() + noMargin = false; + @Input() set error(value) { if (value && !this.message) { 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 341408a615..3fca1fad78 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1188,7 +1188,9 @@ "delta-calculation-result": "Delta calculation result", "delta-calculation-result-previous-value": "Previous value", "delta-calculation-result-delta-absolute": "Delta (absolute)", - "delta-calculation-result-delta-percent": "Delta (percent)" + "delta-calculation-result-delta-percent": "Delta (percent)", + "source": "Source", + "latest": "Latest" }, "datasource": { "type": "Datasource type", @@ -5240,7 +5242,9 @@ "table-header": "Table header", "header-buttons": "Header buttons", "pagination": "Pagination", - "rows": "Rows" + "rows": "Rows", + "timeseries-column-error": "At least one timeseries column should be specified", + "table-tabs": "Table tabs" }, "value-source": { "value-source": "Value source", From 0d661ba6cc9326ee9a9008da2e537183d6f6d330 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 27 Jun 2023 18:53:34 +0300 Subject: [PATCH 207/207] UI: Timeseries table config improvement --- .../cards/timeseries-table-widget-settings.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html index b2743142a4..5cbed7da88 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html @@ -69,8 +69,8 @@ {{ 'widgets.table.use-entity-label-tab-name' | translate }}
-
-
widgets.table.rows
+
+
widgets.table.rows
{{ 'widgets.table.hide-empty-lines' | translate }}