@c8y/ngx-components 1021.22.54 → 1021.22.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/common/interval-based-reload.abstract.d.ts +13 -3
- package/core/common/interval-based-reload.abstract.d.ts.map +1 -1
- package/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.d.ts +5 -4
- package/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.d.ts.map +1 -1
- package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.component.d.ts.map +1 -1
- package/core/dashboard/widgets-dashboard-event.service.d.ts +1 -0
- package/core/dashboard/widgets-dashboard-event.service.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts +9 -3
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts.map +1 -1
- package/core/login/login.component.d.ts.map +1 -1
- package/core/login/login.model.d.ts +8 -0
- package/core/login/login.model.d.ts.map +1 -1
- package/core/login/login.service.d.ts +2 -1
- package/core/login/login.service.d.ts.map +1 -1
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts +11 -8
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts.map +1 -1
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts +4 -2
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts.map +1 -1
- package/datapoints-export-selector/datapoints-export-selector.component.d.ts +6 -2
- package/datapoints-export-selector/datapoints-export-selector.component.d.ts.map +1 -1
- package/datapoints-export-selector/datapoints-export-selector.model.d.ts +17 -0
- package/datapoints-export-selector/datapoints-export-selector.model.d.ts.map +1 -1
- package/esm2022/core/common/aggregation/aggregation.model.mjs +2 -2
- package/esm2022/core/common/interval-based-reload.abstract.mjs +13 -13
- package/esm2022/core/dashboard/dashboard-child.component.mjs +3 -3
- package/esm2022/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.mjs +12 -10
- package/esm2022/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.component.mjs +2 -2
- package/esm2022/core/dashboard/widgets-dashboard-event.service.mjs +10 -1
- package/esm2022/core/dashboard/widgets-dashboard.component.mjs +3 -3
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.mjs +3 -3
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context.component.mjs +37 -15
- package/esm2022/core/login/login.component.mjs +4 -4
- package/esm2022/core/login/login.model.mjs +1 -1
- package/esm2022/core/login/login.service.mjs +7 -3
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.mjs +22 -27
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.mjs +29 -6
- package/esm2022/datapoints-export-selector/datapoints-export-selector.component.mjs +18 -8
- package/esm2022/datapoints-export-selector/datapoints-export-selector.model.mjs +18 -1
- package/esm2022/interval-picker/interval-picker.model.mjs +5 -1
- package/esm2022/widgets/definitions/datapoints-table/index.mjs +3 -2
- package/esm2022/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.mjs +3 -3
- package/esm2022/widgets/implementations/alarms/alarm-widget-alarms-reload.component.mjs +17 -100
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.mjs +45 -41
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.mjs +35 -13
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/datapoints-table.component.mjs +3 -3
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.mjs +81 -38
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-widget.model.mjs +3 -5
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +79 -36
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-interval-picker.mjs +5 -1
- package/fesm2022/c8y-ngx-components-interval-picker.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs +2 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +18 -101
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +152 -88
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +84 -47
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/interval-picker/interval-picker.model.d.ts +6 -0
- package/interval-picker/interval-picker.model.d.ts.map +1 -1
- package/locales/de.po +60 -62
- package/locales/es.po +10 -12
- package/locales/fr.po +109 -109
- package/locales/ja_JP.po +149 -94
- package/locales/ko.po +10 -12
- package/locales/locales.pot +3 -4
- package/locales/nl.po +11 -13
- package/locales/pl.po +11 -13
- package/locales/pt_BR.po +9 -11
- package/locales/zh_CN.po +9 -11
- package/locales/zh_TW.po +11 -13
- package/package.json +1 -1
- package/widgets/definitions/datapoints-table/index.d.ts.map +1 -1
- package/widgets/implementations/alarms/alarm-widget-alarms-reload.component.d.ts +18 -63
- package/widgets/implementations/alarms/alarm-widget-alarms-reload.component.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts +4 -3
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.d.ts +16 -8
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts +23 -5
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts +4 -1
- package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts.map +1 -1
|
@@ -3,33 +3,32 @@ import { Injectable, EventEmitter, inject, Component, ChangeDetectionStrategy, I
|
|
|
3
3
|
import * as i3 from '@angular/forms';
|
|
4
4
|
import { ControlContainer, ReactiveFormsModule, FormControl, Validators } from '@angular/forms';
|
|
5
5
|
import * as i1$1 from '@c8y/ngx-components';
|
|
6
|
-
import { gettext, CoreModule, AGGREGATION_VALUES, AGGREGATION_LABELS, AGGREGATION_VALUES_ARR, IntervalBasedReload, CountdownIntervalComponent, CommonModule as CommonModule$1, CountdownIntervalModule, ListGroupModule, DynamicComponentAlertAggregator, DynamicComponentAlert, DocsModule, DynamicComponentModule, DismissAlertStrategy } from '@c8y/ngx-components';
|
|
6
|
+
import { gettext, CoreModule, AGGREGATION_VALUES, AGGREGATION_LABELS, AGGREGATION_VALUES_ARR, IntervalBasedReload, CountdownIntervalComponent, CommonModule as CommonModule$1, CountdownIntervalModule, ListGroupModule, DynamicComponentAlertAggregator, DynamicComponentAlert, DocsModule, DynamicComponentModule, DismissAlertStrategy, globalAutoRefreshLoading } from '@c8y/ngx-components';
|
|
7
7
|
import * as i4 from '@c8y/ngx-components/context-dashboard';
|
|
8
8
|
import * as i7 from '@c8y/ngx-components/datapoint-selector';
|
|
9
9
|
import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
|
|
10
|
+
import * as i2$1 from '@c8y/ngx-components/datapoints-export-selector';
|
|
10
11
|
import { TIME_RANGE_INTERVAL_UNITS_VALUES, dateRangeValidator } from '@c8y/ngx-components/datapoints-export-selector';
|
|
12
|
+
import { INTERVALS, INTERVAL_VALUES } from '@c8y/ngx-components/interval-picker';
|
|
11
13
|
import * as i8 from 'ngx-bootstrap/popover';
|
|
12
14
|
import { PopoverModule } from 'ngx-bootstrap/popover';
|
|
13
|
-
import { Subject, takeUntil, merge, debounceTime } from 'rxjs';
|
|
15
|
+
import { Subject, takeUntil, merge, tap, BehaviorSubject, debounceTime } from 'rxjs';
|
|
14
16
|
import * as i1 from '@c8y/client';
|
|
15
17
|
import { aggregationType } from '@c8y/client';
|
|
16
18
|
import * as i2 from '@angular/common';
|
|
17
19
|
import { CommonModule } from '@angular/common';
|
|
18
|
-
import { INTERVALS } from '@c8y/ngx-components/interval-picker';
|
|
19
20
|
import * as i1$2 from '@ngx-translate/core';
|
|
20
21
|
import * as i4$1 from 'ngx-bootstrap/tooltip';
|
|
21
22
|
import { TooltipModule } from 'ngx-bootstrap/tooltip';
|
|
22
23
|
|
|
23
24
|
const DEFAULT_COUNTDOWN_VALUE = 30_000;
|
|
24
25
|
const DATE_SELECTION_VALUES = {
|
|
25
|
-
|
|
26
|
-
// dashboard_context: 'dashboard_context',
|
|
26
|
+
dashboard_context: 'dashboard_context',
|
|
27
27
|
config: 'config',
|
|
28
28
|
view_and_config: 'view_and_config'
|
|
29
29
|
};
|
|
30
30
|
const DATE_SELECTION_VALUES_ARR = [
|
|
31
|
-
|
|
32
|
-
// DATE_SELECTION_VALUES.dashboard_context,
|
|
31
|
+
DATE_SELECTION_VALUES.dashboard_context,
|
|
33
32
|
DATE_SELECTION_VALUES.config,
|
|
34
33
|
DATE_SELECTION_VALUES.view_and_config
|
|
35
34
|
];
|
|
@@ -766,10 +765,8 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
766
765
|
this.widgetConfig = widgetConfig;
|
|
767
766
|
this.AGGREGATION_LABELS = AGGREGATION_LABELS;
|
|
768
767
|
this.DATE_SELECTION_LABELS = DATE_SELECTION_LABELS;
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
this.DEFAULT_DATE_SELECTOR_VALUE = DATE_SELECTION_VALUES.config;
|
|
772
|
-
this.DEFAULT_INTERVAL_VALUE = TIME_RANGE_INTERVAL_UNITS_VALUES.hours;
|
|
768
|
+
this.DEFAULT_DATE_SELECTOR_VALUE = DATE_SELECTION_VALUES.dashboard_context;
|
|
769
|
+
this.DEFAULT_INTERVAL_VALUE = INTERVAL_VALUES.hours;
|
|
773
770
|
this.TIME_RANGE_INTERVAL_LABELS = TIME_RANGE_INTERVAL_LABELS;
|
|
774
771
|
this.AGGREGATION_VALUES_ARR = AGGREGATION_VALUES_ARR;
|
|
775
772
|
this.DATE_SELECTION_VALUES_ARR = DATE_SELECTION_VALUES_ARR;
|
|
@@ -802,14 +799,11 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
802
799
|
this.destroy$ = new Subject();
|
|
803
800
|
}
|
|
804
801
|
ngOnInit() {
|
|
805
|
-
// Condition will be removed in MTM-61920
|
|
806
|
-
if (this.config.widgetInstanceGlobalTimeContext) {
|
|
807
|
-
this.config.widgetInstanceGlobalTimeContext = false;
|
|
808
|
-
}
|
|
809
802
|
if (this.widgetConfig.context?.id) {
|
|
810
803
|
this.datapointSelectionConfig.contextAsset = this.widgetConfig?.context;
|
|
811
804
|
}
|
|
812
|
-
this.isWidgetLinkedToGlobalTimeContext =
|
|
805
|
+
this.isWidgetLinkedToGlobalTimeContext =
|
|
806
|
+
this.config.widgetInstanceGlobalAutoRefreshContext ?? true;
|
|
813
807
|
this.initForm();
|
|
814
808
|
this.handleAutoRefreshToggleChanges();
|
|
815
809
|
this.handleIntervalSelectorChanges();
|
|
@@ -826,8 +820,7 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
826
820
|
if (this.formGroup.value.aggregation === AGGREGATION_VALUES.none ||
|
|
827
821
|
(!this.formGroup.value.aggregation && config.aggregation === AGGREGATION_VALUES.none)) {
|
|
828
822
|
// The 'NONE' aggregation type is not handled by a backend, so it simply needs to be deleted to get data without aggregation.
|
|
829
|
-
|
|
830
|
-
delete config.aggregation;
|
|
823
|
+
this.deleteAggregationProperty(config);
|
|
831
824
|
}
|
|
832
825
|
this.updateTimeContext(config, this.formGroup.value.globalDateSelector);
|
|
833
826
|
Object.assign(config, this.formGroup.value);
|
|
@@ -839,19 +832,21 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
839
832
|
}
|
|
840
833
|
updateTimeContext(config, selectedDateContext) {
|
|
841
834
|
switch (selectedDateContext) {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
835
|
+
case DATE_SELECTION_VALUES.dashboard_context:
|
|
836
|
+
config.displayDateSelection = false;
|
|
837
|
+
config.widgetInstanceGlobalAutoRefreshContext = true;
|
|
838
|
+
if (config.aggregation !== 'NONE') {
|
|
839
|
+
this.deleteAggregationProperty(config);
|
|
840
|
+
}
|
|
841
|
+
break;
|
|
847
842
|
case DATE_SELECTION_VALUES.view_and_config:
|
|
848
843
|
config.displayDateSelection = true;
|
|
849
|
-
config.
|
|
844
|
+
config.widgetInstanceGlobalAutoRefreshContext = false;
|
|
850
845
|
break;
|
|
851
846
|
case DATE_SELECTION_VALUES.config:
|
|
852
847
|
default:
|
|
853
848
|
config.displayDateSelection = false;
|
|
854
|
-
config.
|
|
849
|
+
config.widgetInstanceGlobalAutoRefreshContext = false;
|
|
855
850
|
}
|
|
856
851
|
}
|
|
857
852
|
initForm() {
|
|
@@ -865,7 +860,8 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
865
860
|
}
|
|
866
861
|
createForm() {
|
|
867
862
|
const { dateFrom, dateTo } = this.datapointsTableService.calculateDateRange(this.DEFAULT_INTERVAL_VALUE);
|
|
868
|
-
const isLegacyWidget = this.config.
|
|
863
|
+
const isLegacyWidget = this.config.hasOwnProperty('widgetInstanceGlobalTimeContext') &&
|
|
864
|
+
!this.config.hasOwnProperty('decimalPlaces');
|
|
869
865
|
return this.formBuilder.group({
|
|
870
866
|
aggregation: new FormControl({
|
|
871
867
|
value: AGGREGATION_VALUES.none,
|
|
@@ -877,7 +873,7 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
877
873
|
minOneDatapointActive()
|
|
878
874
|
]),
|
|
879
875
|
globalDateSelector: new FormControl(isLegacyWidget
|
|
880
|
-
? this.
|
|
876
|
+
? this.determineGlobalDateSelectorValueForLegacyWidget()
|
|
881
877
|
: this.DEFAULT_DATE_SELECTOR_VALUE),
|
|
882
878
|
dateFrom: new FormControl(dateFrom),
|
|
883
879
|
dateTo: new FormControl(dateTo),
|
|
@@ -898,13 +894,16 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
898
894
|
})
|
|
899
895
|
}, { validators: dateRangeValidator });
|
|
900
896
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
if (
|
|
906
|
-
return DATE_SELECTION_VALUES.
|
|
897
|
+
determineGlobalDateSelectorValueForLegacyWidget() {
|
|
898
|
+
const { displayDateSelection, widgetInstanceGlobalAutoRefreshContext } = this.config;
|
|
899
|
+
// State of widgetInstanceGlobalTimeContext was converted to widgetInstanceGlobalAutoRefreshContext.
|
|
900
|
+
// That is why it use here in a legacy widget context.
|
|
901
|
+
if (widgetInstanceGlobalAutoRefreshContext) {
|
|
902
|
+
return DATE_SELECTION_VALUES.dashboard_context;
|
|
907
903
|
}
|
|
904
|
+
return displayDateSelection
|
|
905
|
+
? DATE_SELECTION_VALUES.view_and_config
|
|
906
|
+
: DATE_SELECTION_VALUES.config;
|
|
908
907
|
}
|
|
909
908
|
isAutoRefershDisabled() {
|
|
910
909
|
const isInitialWidgetCreation = Object.keys(this.config).length === 1 && this.config['settings'];
|
|
@@ -912,9 +911,9 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
912
911
|
return false;
|
|
913
912
|
}
|
|
914
913
|
const isLegacyWidgetRealtimeNotActive = !this.config.realtime &&
|
|
915
|
-
!this.config.decimalPlaces &&
|
|
916
|
-
!this.config.refreshInterval &&
|
|
917
|
-
!this.config.isAutoRefreshEnabled;
|
|
914
|
+
!this.config.hasOwnProperty('decimalPlaces') &&
|
|
915
|
+
!this.config.hasOwnProperty('refreshInterval') &&
|
|
916
|
+
!this.config.hasOwnProperty('isAutoRefreshEnabled');
|
|
918
917
|
if (isLegacyWidgetRealtimeNotActive) {
|
|
919
918
|
return true;
|
|
920
919
|
}
|
|
@@ -1032,14 +1031,13 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
1032
1031
|
handleGlobalDateSelectorChanges() {
|
|
1033
1032
|
this.formGroup.controls.globalDateSelector.valueChanges
|
|
1034
1033
|
.pipe(takeUntil(this.destroy$))
|
|
1035
|
-
.subscribe(() => {
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
// }
|
|
1034
|
+
.subscribe((selected) => {
|
|
1035
|
+
if (selected === DATE_SELECTION_VALUES.dashboard_context) {
|
|
1036
|
+
this.handleDashboardContext();
|
|
1037
|
+
}
|
|
1038
|
+
else {
|
|
1039
|
+
this.handleNonDashboardContext();
|
|
1040
|
+
}
|
|
1043
1041
|
});
|
|
1044
1042
|
}
|
|
1045
1043
|
handleDashboardContext() {
|
|
@@ -1054,7 +1052,7 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
1054
1052
|
this.setIntervalToCustom(this.formGroup.controls.interval);
|
|
1055
1053
|
}
|
|
1056
1054
|
isConfigSavedWithoutDashboardTimeOption() {
|
|
1057
|
-
return !this.config.
|
|
1055
|
+
return !this.config.widgetInstanceGlobalAutoRefreshContext;
|
|
1058
1056
|
}
|
|
1059
1057
|
updateAggregationIfNecessary() {
|
|
1060
1058
|
const aggregationControl = this.formGroup.controls.aggregation;
|
|
@@ -1090,8 +1088,12 @@ class DatapointsTableWidgetConfigComponent {
|
|
|
1090
1088
|
aggregationControl.setValue(newAggregationValue);
|
|
1091
1089
|
}
|
|
1092
1090
|
}
|
|
1091
|
+
deleteAggregationProperty(config) {
|
|
1092
|
+
delete this.formGroup.value.aggregation;
|
|
1093
|
+
delete config.aggregation;
|
|
1094
|
+
}
|
|
1093
1095
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableWidgetConfigComponent, deps: [{ token: DatapointsTableService }, { token: DatapointsTableConfigService }, { token: i3.FormBuilder }, { token: i3.NgForm }, { token: i4.WidgetConfigComponent }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1094
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: DatapointsTableWidgetConfigComponent, isStandalone: true, selector: "c8y-datapoints-table-view-config", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24\">\n <form\n class=\"no-card-context\"\n [formGroup]=\"formGroup\"\n >\n <!-- <datapoints-selector> -->\n <div class=\"col-md-6\">\n <div class=\"row\">\n <!-- global-time-context-selector -->\n <div class=\"form-group m-b-0 p-b-16 separator-bottom\">\n <label\n class=\"d-flex a-i-center p-t-4\"\n for=\"dateSelection\"\n >\n {{ 'Date selection' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"popoverTemplate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n <ng-template #popoverTemplate>\n <span translate>\n Choose how to select a date range, the available options are:\n <ul class=\"m-l-0 p-l-8 m-t-8 m-b-0\">\n <!-- Will be re-enabled in MTM-61920 -->\n <!-- <li>\n <b>Dashboard time range:</b>\n restricts date selection to the global dashboard configuration only\n </li> -->\n <li>\n <b>Widget configuration:</b>\n restricts the date selection only to the widget configuration\n </li>\n <li>\n <b>Widget and widget configuration:</b>\n restricts the date selection to the widget view and widget configuration only\n </li>\n </ul>\n </span>\n </ng-template>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Date selection' | translate\"\n [attr.aria-label]=\"'Date selection' | translate\"\n id=\"globalDateSelector\"\n formControlName=\"globalDateSelector\"\n >\n <option\n *ngFor=\"let dataSelectionValue of DATE_SELECTION_VALUES_ARR\"\n [ngValue]=\"dataSelectionValue\"\n >\n {{ DATE_SELECTION_LABELS[dataSelectionValue] | translate }}\n </option>\n </select>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Data points' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"1\"\n formControlName=\"datapoints\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"row\">\n <ng-container *ngIf=\"!isWidgetLinkedToGlobalTimeContext\">\n <div class=\"col-md-6\">\n <!-- interval selector -->\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex a-i-center\">\n {{ 'Auto refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"\n 'Change the state of interval automatic refresh and set the refresh frequency.'\n | translate\n \"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-16 form-group-sm\">\n <div class=\"d-flex gap-4 m-t-8 m-b-8 a-i-center\">\n <label class=\"c8y-switch\">\n <input\n id=\"refreshToggle\"\n name=\"isAutoRefreshEnabled\"\n type=\"checkbox\"\n formControlName=\"isAutoRefreshEnabled\"\n (click)=\"toggleRefreshIntervalControl()\"\n />\n <span></span>\n <span class=\"sr-only\">{{ 'Auto refresh' | translate }}</span>\n </label>\n <label\n class=\"m-b-0\"\n for=\"refreshInterval\"\n >\n {{ 'Interval' | translate }}\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Refresh interval in seconds' | translate\"\n id=\"refreshInterval\"\n formControlName=\"refreshInterval\"\n >\n <option\n *ngFor=\"let refreshInterval of REFRESH_INTERVAL_VALUES_ARR\"\n [ngValue]=\"refreshInterval\"\n >\n {{ '{{ seconds }} s' | translate: { seconds: refreshInterval / 1000 } }}\n </option>\n </select>\n </div>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n </ng-container>\n <!-- decimal input -->\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Decimal places' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <input\n class=\"form-control\"\n name=\"decimalPlaces\"\n type=\"number\"\n formControlName=\"decimalPlaces\"\n step=\"1\"\n />\n </c8y-form-group>\n </fieldset>\n </div>\n </div>\n <!-- aggregation selector -->\n <ng-container *ngIf=\"!isWidgetLinkedToGlobalTimeContext\">\n <div class=\"row\">\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Aggregation' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <div class=\"c8y-select-wrapper\">\n <!-- Setting below [attr.disabled] ensures that the control is visually disabled and user interaction is prevented,\n while still allowing the value to be updated and saved correctly in the form.\n This solution covers the case where the user enables auto-refresh, in which case aggregation must be set to NONE. -->\n <select\n class=\"form-control text-12\"\n [title]=\"'Aggregation' | translate\"\n id=\"aggregation\"\n formControlName=\"aggregation\"\n [attr.disabled]=\"formGroup.value.isAutoRefreshEnabled ? true : null\"\n >\n <option\n *ngFor=\"let aggregationValue of AGGREGATION_VALUES_ARR\"\n [ngValue]=\"aggregationValue\"\n [disabled]=\"disabledAggregationOptions[aggregationValue]\"\n >\n {{ AGGREGATION_LABELS[aggregationValue] | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n <!-- time interval selector -->\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Time interval' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Interval' | translate\"\n id=\"interval\"\n formControlName=\"interval\"\n >\n <option\n *ngFor=\"let intervalValue of INTERVAL_VALUES_ARR\"\n [ngValue]=\"intervalValue\"\n >\n {{ TIME_RANGE_INTERVAL_LABELS[intervalValue] | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n </div>\n <!-- date pickers -->\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Date range' | translate }}\n </legend>\n <c8y-date-range-picker></c8y-date-range-picker>\n </fieldset>\n </ng-container>\n </div>\n </form>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "pipe", type: i1$1.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i1$1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i1$1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i1$1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i7.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "component", type: DateRangePickerComponent, selector: "c8y-date-range-picker", inputs: ["isEmittingDateChange", "showLabel"], outputs: ["updatedDate"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i8.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "ngmodule", type: ReactiveFormsModule }] }); }
|
|
1096
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: DatapointsTableWidgetConfigComponent, isStandalone: true, selector: "c8y-datapoints-table-view-config", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24\">\n <form\n class=\"no-card-context\"\n [formGroup]=\"formGroup\"\n >\n <!-- <datapoints-selector> -->\n <div class=\"col-md-6\">\n <div class=\"row\">\n <!-- global-time-context-selector -->\n <div class=\"form-group m-b-0 p-b-16 separator-bottom\">\n <label\n class=\"d-flex a-i-center p-t-4\"\n for=\"dateSelection\"\n >\n {{ 'Date selection' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"popoverTemplate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n <ng-template #popoverTemplate>\n <span translate>\n Choose how to select a date range, the available options are:\n <ul class=\"m-l-0 p-l-8 m-t-8 m-b-0\">\n <li>\n <b>Dashboard time range:</b>\n restricts date selection to the global dashboard configuration only\n </li>\n <li>\n <b>Widget configuration:</b>\n restricts the date selection only to the widget configuration\n </li>\n <li>\n <b>Widget and widget configuration:</b>\n restricts the date selection to the widget view and widget configuration only\n </li>\n </ul>\n </span>\n </ng-template>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Date selection' | translate\"\n [attr.aria-label]=\"'Date selection' | translate\"\n id=\"globalDateSelector\"\n formControlName=\"globalDateSelector\"\n >\n <option\n *ngFor=\"let dataSelectionValue of DATE_SELECTION_VALUES_ARR\"\n [ngValue]=\"dataSelectionValue\"\n >\n {{ DATE_SELECTION_LABELS[dataSelectionValue] | translate }}\n </option>\n </select>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Data points' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"1\"\n formControlName=\"datapoints\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"row\">\n <ng-container *ngIf=\"!isWidgetLinkedToGlobalTimeContext\">\n <div class=\"col-md-6\">\n <!-- interval selector -->\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex a-i-center\">\n {{ 'Auto refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"\n 'Change the state of interval automatic refresh and set the refresh frequency.'\n | translate\n \"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-16 form-group-sm\">\n <div class=\"d-flex gap-4 m-t-8 m-b-8 a-i-center\">\n <label class=\"c8y-switch\">\n <input\n id=\"refreshToggle\"\n name=\"isAutoRefreshEnabled\"\n type=\"checkbox\"\n formControlName=\"isAutoRefreshEnabled\"\n (click)=\"toggleRefreshIntervalControl()\"\n />\n <span></span>\n <span class=\"sr-only\">{{ 'Auto refresh' | translate }}</span>\n </label>\n <label\n class=\"m-b-0\"\n for=\"refreshInterval\"\n >\n {{ 'Interval' | translate }}\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Refresh interval in seconds' | translate\"\n id=\"refreshInterval\"\n formControlName=\"refreshInterval\"\n >\n <option\n *ngFor=\"let refreshInterval of REFRESH_INTERVAL_VALUES_ARR\"\n [ngValue]=\"refreshInterval\"\n >\n {{ '{{ seconds }} s' | translate: { seconds: refreshInterval / 1000 } }}\n </option>\n </select>\n </div>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n </ng-container>\n <!-- decimal input -->\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Decimal places' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <input\n class=\"form-control\"\n name=\"decimalPlaces\"\n type=\"number\"\n formControlName=\"decimalPlaces\"\n step=\"1\"\n />\n </c8y-form-group>\n </fieldset>\n </div>\n </div>\n <!-- aggregation selector -->\n <div class=\"row\">\n <ng-container *ngIf=\"!isWidgetLinkedToGlobalTimeContext\">\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Aggregation' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <div class=\"c8y-select-wrapper\">\n <!-- Setting below [attr.disabled] ensures that the control is visually disabled and user interaction is prevented,\n while still allowing the value to be updated and saved correctly in the form.\n This solution covers the case where the user enables auto-refresh, in which case aggregation must be set to NONE. -->\n <select\n class=\"form-control text-12\"\n [title]=\"'Aggregation' | translate\"\n id=\"aggregation\"\n formControlName=\"aggregation\"\n [attr.disabled]=\"formGroup.value.isAutoRefreshEnabled ? true : null\"\n >\n <option\n *ngFor=\"let aggregationValue of AGGREGATION_VALUES_ARR\"\n [ngValue]=\"aggregationValue\"\n [disabled]=\"disabledAggregationOptions[aggregationValue]\"\n >\n {{ AGGREGATION_LABELS[aggregationValue] | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n </ng-container>\n <!-- time interval selector -->\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Time interval' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Interval' | translate\"\n id=\"interval\"\n formControlName=\"interval\"\n >\n <option\n *ngFor=\"let intervalValue of INTERVAL_VALUES_ARR\"\n [ngValue]=\"intervalValue\"\n >\n {{ TIME_RANGE_INTERVAL_LABELS[intervalValue] | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n </div>\n <!-- date pickers -->\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Date range' | translate }}\n </legend>\n <c8y-date-range-picker></c8y-date-range-picker>\n </fieldset>\n </div>\n </form>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "pipe", type: i1$1.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i1$1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i1$1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i1$1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i7.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "component", type: DateRangePickerComponent, selector: "c8y-date-range-picker", inputs: ["isEmittingDateChange", "showLabel"], outputs: ["updatedDate"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i8.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "ngmodule", type: ReactiveFormsModule }] }); }
|
|
1095
1097
|
}
|
|
1096
1098
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableWidgetConfigComponent, decorators: [{
|
|
1097
1099
|
type: Component,
|
|
@@ -1101,7 +1103,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
|
|
|
1101
1103
|
DateRangePickerComponent,
|
|
1102
1104
|
PopoverModule,
|
|
1103
1105
|
ReactiveFormsModule
|
|
1104
|
-
], template: "<div class=\"p-l-24 p-r-24\">\n <form\n class=\"no-card-context\"\n [formGroup]=\"formGroup\"\n >\n <!-- <datapoints-selector> -->\n <div class=\"col-md-6\">\n <div class=\"row\">\n <!-- global-time-context-selector -->\n <div class=\"form-group m-b-0 p-b-16 separator-bottom\">\n <label\n class=\"d-flex a-i-center p-t-4\"\n for=\"dateSelection\"\n >\n {{ 'Date selection' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"popoverTemplate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n <ng-template #popoverTemplate>\n <span translate>\n Choose how to select a date range, the available options are:\n <ul class=\"m-l-0 p-l-8 m-t-8 m-b-0\">\n
|
|
1106
|
+
], template: "<div class=\"p-l-24 p-r-24\">\n <form\n class=\"no-card-context\"\n [formGroup]=\"formGroup\"\n >\n <!-- <datapoints-selector> -->\n <div class=\"col-md-6\">\n <div class=\"row\">\n <!-- global-time-context-selector -->\n <div class=\"form-group m-b-0 p-b-16 separator-bottom\">\n <label\n class=\"d-flex a-i-center p-t-4\"\n for=\"dateSelection\"\n >\n {{ 'Date selection' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"popoverTemplate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n <ng-template #popoverTemplate>\n <span translate>\n Choose how to select a date range, the available options are:\n <ul class=\"m-l-0 p-l-8 m-t-8 m-b-0\">\n <li>\n <b>Dashboard time range:</b>\n restricts date selection to the global dashboard configuration only\n </li>\n <li>\n <b>Widget configuration:</b>\n restricts the date selection only to the widget configuration\n </li>\n <li>\n <b>Widget and widget configuration:</b>\n restricts the date selection to the widget view and widget configuration only\n </li>\n </ul>\n </span>\n </ng-template>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Date selection' | translate\"\n [attr.aria-label]=\"'Date selection' | translate\"\n id=\"globalDateSelector\"\n formControlName=\"globalDateSelector\"\n >\n <option\n *ngFor=\"let dataSelectionValue of DATE_SELECTION_VALUES_ARR\"\n [ngValue]=\"dataSelectionValue\"\n >\n {{ DATE_SELECTION_LABELS[dataSelectionValue] | translate }}\n </option>\n </select>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Data points' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"1\"\n formControlName=\"datapoints\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"row\">\n <ng-container *ngIf=\"!isWidgetLinkedToGlobalTimeContext\">\n <div class=\"col-md-6\">\n <!-- interval selector -->\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex a-i-center\">\n {{ 'Auto refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"\n 'Change the state of interval automatic refresh and set the refresh frequency.'\n | translate\n \"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"m-b-16 form-group-sm\">\n <div class=\"d-flex gap-4 m-t-8 m-b-8 a-i-center\">\n <label class=\"c8y-switch\">\n <input\n id=\"refreshToggle\"\n name=\"isAutoRefreshEnabled\"\n type=\"checkbox\"\n formControlName=\"isAutoRefreshEnabled\"\n (click)=\"toggleRefreshIntervalControl()\"\n />\n <span></span>\n <span class=\"sr-only\">{{ 'Auto refresh' | translate }}</span>\n </label>\n <label\n class=\"m-b-0\"\n for=\"refreshInterval\"\n >\n {{ 'Interval' | translate }}\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Refresh interval in seconds' | translate\"\n id=\"refreshInterval\"\n formControlName=\"refreshInterval\"\n >\n <option\n *ngFor=\"let refreshInterval of REFRESH_INTERVAL_VALUES_ARR\"\n [ngValue]=\"refreshInterval\"\n >\n {{ '{{ seconds }} s' | translate: { seconds: refreshInterval / 1000 } }}\n </option>\n </select>\n </div>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n </ng-container>\n <!-- decimal input -->\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Decimal places' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <input\n class=\"form-control\"\n name=\"decimalPlaces\"\n type=\"number\"\n formControlName=\"decimalPlaces\"\n step=\"1\"\n />\n </c8y-form-group>\n </fieldset>\n </div>\n </div>\n <!-- aggregation selector -->\n <div class=\"row\">\n <ng-container *ngIf=\"!isWidgetLinkedToGlobalTimeContext\">\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Aggregation' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <div class=\"c8y-select-wrapper\">\n <!-- Setting below [attr.disabled] ensures that the control is visually disabled and user interaction is prevented,\n while still allowing the value to be updated and saved correctly in the form.\n This solution covers the case where the user enables auto-refresh, in which case aggregation must be set to NONE. -->\n <select\n class=\"form-control text-12\"\n [title]=\"'Aggregation' | translate\"\n id=\"aggregation\"\n formControlName=\"aggregation\"\n [attr.disabled]=\"formGroup.value.isAutoRefreshEnabled ? true : null\"\n >\n <option\n *ngFor=\"let aggregationValue of AGGREGATION_VALUES_ARR\"\n [ngValue]=\"aggregationValue\"\n [disabled]=\"disabledAggregationOptions[aggregationValue]\"\n >\n {{ AGGREGATION_LABELS[aggregationValue] | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n </ng-container>\n <!-- time interval selector -->\n <div class=\"col-md-6\">\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Time interval' | translate }}\n </legend>\n <c8y-form-group class=\"p-t-8\">\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control text-12\"\n [title]=\"'Interval' | translate\"\n id=\"interval\"\n formControlName=\"interval\"\n >\n <option\n *ngFor=\"let intervalValue of INTERVAL_VALUES_ARR\"\n [ngValue]=\"intervalValue\"\n >\n {{ TIME_RANGE_INTERVAL_LABELS[intervalValue] | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </fieldset>\n </div>\n </div>\n <!-- date pickers -->\n <fieldset class=\"c8y-fieldset\">\n <legend>\n {{ 'Date range' | translate }}\n </legend>\n <c8y-date-range-picker></c8y-date-range-picker>\n </fieldset>\n </div>\n </form>\n</div>\n" }]
|
|
1105
1107
|
}], ctorParameters: () => [{ type: DatapointsTableService }, { type: DatapointsTableConfigService }, { type: i3.FormBuilder }, { type: i3.NgForm }, { type: i4.WidgetConfigComponent }], propDecorators: { config: [{
|
|
1106
1108
|
type: Input
|
|
1107
1109
|
}] } });
|
|
@@ -1329,11 +1331,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
|
|
|
1329
1331
|
}] });
|
|
1330
1332
|
|
|
1331
1333
|
class DatapointsReloadComponent extends IntervalBasedReload {
|
|
1332
|
-
constructor(cdRef,
|
|
1334
|
+
constructor(cdRef, translateService, widgetGlobalAutoRefreshService) {
|
|
1333
1335
|
super();
|
|
1334
1336
|
this.cdRef = cdRef;
|
|
1335
|
-
this.injector = injector;
|
|
1336
1337
|
this.translateService = translateService;
|
|
1338
|
+
this.widgetGlobalAutoRefreshService = widgetGlobalAutoRefreshService;
|
|
1339
|
+
/**
|
|
1340
|
+
* @inheritdoc
|
|
1341
|
+
*/
|
|
1342
|
+
this.isRefreshDisabled = false;
|
|
1337
1343
|
/**
|
|
1338
1344
|
* @inheritdoc
|
|
1339
1345
|
*/
|
|
@@ -1342,9 +1348,17 @@ class DatapointsReloadComponent extends IntervalBasedReload {
|
|
|
1342
1348
|
* @inheritdoc
|
|
1343
1349
|
*/
|
|
1344
1350
|
this.manuallyDisabledCountdown = false;
|
|
1351
|
+
this.destroy$ = new Subject();
|
|
1352
|
+
}
|
|
1353
|
+
ngAfterViewInit() {
|
|
1354
|
+
if (this.widgetInstanceGlobalAutoRefreshContext) {
|
|
1355
|
+
this.widgetGlobalAutoRefreshService.countdownActions.countdownEnded$
|
|
1356
|
+
.pipe(takeUntil(this.destroy$), tap(() => this.onCountdownEnded.emit()))
|
|
1357
|
+
.subscribe();
|
|
1358
|
+
}
|
|
1345
1359
|
}
|
|
1346
1360
|
ngOnChanges(changes) {
|
|
1347
|
-
if (this.
|
|
1361
|
+
if (this.isRefreshDisabled && this.isAutoRefreshEnabled) {
|
|
1348
1362
|
this.isIntervalRefreshToggleOn = false;
|
|
1349
1363
|
this.disableCountdown();
|
|
1350
1364
|
return;
|
|
@@ -1356,13 +1370,20 @@ class DatapointsReloadComponent extends IntervalBasedReload {
|
|
|
1356
1370
|
else {
|
|
1357
1371
|
if (this.canStartCountdown(changes)) {
|
|
1358
1372
|
this.isIntervalRefreshToggleOn = true;
|
|
1359
|
-
this.startCountdown(
|
|
1373
|
+
this.startCountdown();
|
|
1360
1374
|
}
|
|
1361
1375
|
if (this.canHandleScrolling()) {
|
|
1362
1376
|
this.handleScrolling();
|
|
1363
1377
|
}
|
|
1364
1378
|
}
|
|
1365
1379
|
}
|
|
1380
|
+
ngOnDestroy() {
|
|
1381
|
+
if (this.countdownSubscription) {
|
|
1382
|
+
this.countdownSubscription.unsubscribe();
|
|
1383
|
+
}
|
|
1384
|
+
this.destroy$.next();
|
|
1385
|
+
this.destroy$.complete();
|
|
1386
|
+
}
|
|
1366
1387
|
/**
|
|
1367
1388
|
* @inheritdoc
|
|
1368
1389
|
*/
|
|
@@ -1385,7 +1406,7 @@ class DatapointsReloadComponent extends IntervalBasedReload {
|
|
|
1385
1406
|
this.hideCountdown = false;
|
|
1386
1407
|
// Prevents the countdown from getting stuck on an initial value.
|
|
1387
1408
|
this.cdRef.detectChanges();
|
|
1388
|
-
this.startCountdown(
|
|
1409
|
+
this.startCountdown();
|
|
1389
1410
|
}
|
|
1390
1411
|
/**
|
|
1391
1412
|
* @inheritdoc
|
|
@@ -1410,18 +1431,18 @@ class DatapointsReloadComponent extends IntervalBasedReload {
|
|
|
1410
1431
|
!this.isScrolling &&
|
|
1411
1432
|
!this.hideCountdown);
|
|
1412
1433
|
}
|
|
1413
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsReloadComponent, deps: [{ token: i0.ChangeDetectorRef }, { token:
|
|
1414
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: DatapointsReloadComponent, isStandalone: true, selector: "c8y-datapoints-reload", inputs: { isAutoRefreshEnabled: "isAutoRefreshEnabled",
|
|
1434
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsReloadComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$2.TranslateService }, { token: i1$1.WidgetGlobalAutoRefreshService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1435
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: DatapointsReloadComponent, isStandalone: true, selector: "c8y-datapoints-reload", inputs: { isAutoRefreshEnabled: "isAutoRefreshEnabled", isRefreshDisabled: "isRefreshDisabled", isLoading: "isLoading", isScrolling: "isScrolling", isExportModalOpen: "isExportModalOpen", refreshInterval: "refreshInterval", widgetInstanceGlobalAutoRefreshContext: "widgetInstanceGlobalAutoRefreshContext" }, outputs: { onCountdownEnded: "onCountdownEnded" }, viewQueries: [{ propertyName: "countdownIntervalComponent", first: true, predicate: CountdownIntervalComponent, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!widgetInstanceGlobalAutoRefreshContext\">\n <div class=\"a-i-center input-group p-t-4 p-b-4 max-width-fit m-l-auto\">\n <label\n class=\"m-b-0 m-r-8 text-label-small text-truncate flex-no-shrink\"\n title=\" {{ 'Auto refresh' | translate }}\"\n *ngIf=\"refreshInterval && isAutoRefreshEnabled\"\n >\n {{ 'Auto refresh' | translate }}\n </label>\n <div class=\"input-group\">\n <label\n class=\"toggle-countdown\"\n [class.toggle-countdown-disabled]=\"isRefreshDisabled\"\n [attr.aria-label]=\"toggleCountdownButtonTooltipText\"\n [tooltip]=\"toggleCountdownButtonTooltipText\"\n placement=\"bottom\"\n *ngIf=\"refreshInterval && isAutoRefreshEnabled\"\n [adaptivePosition]=\"false\"\n [container]=\"'body'\"\n [delay]=\"500\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"isIntervalRefreshToggleOn\"\n [disabled]=\"isRefreshDisabled\"\n data-cy=\"c8y-data-points-table-widget--interval-toggle-button\"\n (click)=\"onToggleCountdownButtonState($event)\"\n />\n\n <c8y-countdown-interval\n *ngIf=\"isIntervalRefreshToggleOn\"\n [countdownInterval]=\"refreshInterval\"\n (countdownEnded)=\"countdownEnded()\"\n ></c8y-countdown-interval>\n <i\n c8yIcon=\"pause\"\n *ngIf=\"!isIntervalRefreshToggleOn\"\n ></i>\n </label>\n\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [container]=\"'body'\"\n [delay]=\"500\"\n [disabled]=\"isRefreshDisabled || (isLoading | async)\"\n (click)=\"reload()\"\n data-cy=\"c8y-data-points-table-widget--reload-button\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading | async }\"\n ></i>\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i1$1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i1$1.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "ngmodule", type: CountdownIntervalModule }, { kind: "component", type: i1$1.CountdownIntervalComponent, selector: "c8y-countdown-interval", inputs: ["countdownInterval"], outputs: ["countdownEnded"] }, { kind: "ngmodule", type: ListGroupModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i4$1.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }] }); }
|
|
1415
1436
|
}
|
|
1416
1437
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsReloadComponent, decorators: [{
|
|
1417
1438
|
type: Component,
|
|
1418
|
-
args: [{ selector: 'c8y-datapoints-reload', standalone: true, imports: [CommonModule$1, CountdownIntervalModule, ListGroupModule, TooltipModule], template: "<div class=\"
|
|
1419
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type:
|
|
1439
|
+
args: [{ selector: 'c8y-datapoints-reload', standalone: true, imports: [CommonModule$1, CountdownIntervalModule, ListGroupModule, TooltipModule], template: "<ng-container *ngIf=\"!widgetInstanceGlobalAutoRefreshContext\">\n <div class=\"a-i-center input-group p-t-4 p-b-4 max-width-fit m-l-auto\">\n <label\n class=\"m-b-0 m-r-8 text-label-small text-truncate flex-no-shrink\"\n title=\" {{ 'Auto refresh' | translate }}\"\n *ngIf=\"refreshInterval && isAutoRefreshEnabled\"\n >\n {{ 'Auto refresh' | translate }}\n </label>\n <div class=\"input-group\">\n <label\n class=\"toggle-countdown\"\n [class.toggle-countdown-disabled]=\"isRefreshDisabled\"\n [attr.aria-label]=\"toggleCountdownButtonTooltipText\"\n [tooltip]=\"toggleCountdownButtonTooltipText\"\n placement=\"bottom\"\n *ngIf=\"refreshInterval && isAutoRefreshEnabled\"\n [adaptivePosition]=\"false\"\n [container]=\"'body'\"\n [delay]=\"500\"\n >\n <input\n type=\"checkbox\"\n [checked]=\"isIntervalRefreshToggleOn\"\n [disabled]=\"isRefreshDisabled\"\n data-cy=\"c8y-data-points-table-widget--interval-toggle-button\"\n (click)=\"onToggleCountdownButtonState($event)\"\n />\n\n <c8y-countdown-interval\n *ngIf=\"isIntervalRefreshToggleOn\"\n [countdownInterval]=\"refreshInterval\"\n (countdownEnded)=\"countdownEnded()\"\n ></c8y-countdown-interval>\n <i\n c8yIcon=\"pause\"\n *ngIf=\"!isIntervalRefreshToggleOn\"\n ></i>\n </label>\n\n <div class=\"input-group-btn\">\n <button\n class=\"btn btn-default\"\n [attr.aria-label]=\"'Refresh' | translate\"\n [tooltip]=\"'Refresh' | translate\"\n placement=\"bottom\"\n type=\"button\"\n [adaptivePosition]=\"false\"\n [container]=\"'body'\"\n [delay]=\"500\"\n [disabled]=\"isRefreshDisabled || (isLoading | async)\"\n (click)=\"reload()\"\n data-cy=\"c8y-data-points-table-widget--reload-button\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': isLoading | async }\"\n ></i>\n </button>\n </div>\n </div>\n </div>\n</ng-container>\n" }]
|
|
1440
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$2.TranslateService }, { type: i1$1.WidgetGlobalAutoRefreshService }], propDecorators: { countdownIntervalComponent: [{
|
|
1420
1441
|
type: ViewChild,
|
|
1421
1442
|
args: [CountdownIntervalComponent, { static: false }]
|
|
1422
1443
|
}], isAutoRefreshEnabled: [{
|
|
1423
1444
|
type: Input
|
|
1424
|
-
}],
|
|
1445
|
+
}], isRefreshDisabled: [{
|
|
1425
1446
|
type: Input
|
|
1426
1447
|
}], isLoading: [{
|
|
1427
1448
|
type: Input
|
|
@@ -1431,6 +1452,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
|
|
|
1431
1452
|
type: Input
|
|
1432
1453
|
}], refreshInterval: [{
|
|
1433
1454
|
type: Input
|
|
1455
|
+
}], widgetInstanceGlobalAutoRefreshContext: [{
|
|
1456
|
+
type: Input
|
|
1434
1457
|
}], onCountdownEnded: [{
|
|
1435
1458
|
type: Output
|
|
1436
1459
|
}] } });
|
|
@@ -1662,7 +1685,7 @@ class DatapointsTableComponent {
|
|
|
1662
1685
|
}));
|
|
1663
1686
|
}
|
|
1664
1687
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1665
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: DatapointsTableComponent, isStandalone: true, selector: "c8y-datapoints-table", inputs: { aggregationType: "aggregationType", datapointsTableItems: "datapointsTableItems", devicesColumnHeaders: "devicesColumnHeaders", decimalPlaces: "decimalPlaces", hasMultipleDatapoints: "hasMultipleDatapoints", isLoading: "isLoading", seriesWithoutPermissionToReadCount: "seriesWithoutPermissionToReadCount" }, outputs: { isScrolling: "isScrolling" }, host: { classAttribute: "d-col flex-grow" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"c8y-cq-440\">\n <div\n class=\"hidden-xs c8y-list__item c8y-list--timeline hidden-cq\"\n [ngClass]=\"{ 'separator-top-bottom': devicesColumnHeaders.length > 0 }\"\n >\n <div class=\"d-flex container-fluid\">\n <div class=\"c8y-list--timeline__item__date\"></div>\n <div class=\"c8y-list__item__block flex-grow min-width-0\">\n <div class=\"c8y-list__item__body\">\n <div class=\"d-flex row\">\n <ng-container *ngIf=\"hasMultipleDatapoints\">\n <div\n class=\"min-width-0\"\n [title]=\"'Device' | translate\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n >\n <span class=\"text-medium text-truncate\">\n {{ 'Device' | translate }}\n </span>\n </div>\n </ng-container>\n <!-- Data points column headers -->\n <ng-container *ngFor=\"let header of devicesColumnHeaders\">\n <div\n class=\"min-width-0\"\n title=\"{{ header | columnTitle }}\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n >\n <span class=\"text-medium text-truncate\">{{ header.label }} {{ header.unit }}</span>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n<!-- The record list -->\n<ng-container *ngIf=\"!isLoading; else loading\">\n <ng-container *ngIf=\"!hasNoPermissionsToReadAnyMeasurement; else missingAllPermissions\">\n <ng-container *ngIf=\"datapointsTableItems.length; else emptyState\">\n <c8y-list-group\n class=\"p-t-8 flex-grow c8y-cq-440\"\n c8yVirtualScrollListener\n (scrolled)=\"onListScrolled()\"\n (scrolledToTop)=\"onListScrolledToTop()\"\n >\n <c8y-li-timeline\n *c8yFor=\"\n let tableItem of { data: datapointsTableItems, res: null };\n enableVirtualScroll: true;\n virtualScrollElementSize: 40;\n virtualScrollStrategy: 'fixed'\n \"\n >\n {{ tableItem.dateAndTime | c8yDate: 'mediumDate' }}\n {{\n tableItem.dateAndTime\n | c8yDate: 'mediumTime'\n | adjustAggregatedTimeRange: aggregationType\n }}\n <c8y-li>\n <c8y-li-body>\n <div class=\"d-flex row\">\n <div\n class=\"min-width-0\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngIf=\"devicesColumnHeaders.length > 1\"\n [attr.data-label]=\"'Device' | translate\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ tableItem.deviceName }}\"\n >\n {{ tableItem.deviceName }}\n </div>\n </div>\n <!-- Data point value row cells -->\n <ng-container *ngFor=\"let row of tableItem.rowItems\">\n <ng-container *ngIf=\"row !== null; else emptyRowContent\">\n <ng-container [ngSwitch]=\"row.renderType\">\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n *ngSwitchCase=\"'min'\"\n [attr.data-label]=\"row.label\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </div>\n </div>\n <div\n class=\"col-md-4\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n *ngSwitchCase=\"'max'\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </div>\n </div>\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngSwitchCase=\"'area'\"\n >\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n ...\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.max ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n </div>\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngSwitchDefault\n >\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #emptyRowContent>\n <div [c8yDynamicColumn]=\"devicesColumnHeaders.length\"></div>\n </ng-template>\n </ng-container>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n </c8y-list-group>\n </ng-container>\n </ng-container>\n</ng-container>\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n<ng-template #emptyState>\n <div class=\"p-relative p-l-24\">\n <c8y-ui-empty-state\n [icon]=\"'c8y-alert-idle'\"\n [title]=\"'No data to display.' | translate\"\n [horizontal]=\"true\"\n data-cy=\"datapoints-table-list--empty-state\"\n >\n <p c8y-guide-docs>\n <small translate>\n Find out more in the\n <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-table\">\n user documentation\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n </div>\n</ng-template>\n<ng-template #missingAllPermissions>\n <div class=\"p-t-24 p-r-16 p-l-16 p-b-16 d-flex\">\n <div class=\"center-block\">\n <c8y-dynamic-component-alerts\n [alerts]=\"missingAllPermissionsAlert\"\n ></c8y-dynamic-component-alerts>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "pipe", type: AdjustAggregatedTimeRangePipe, name: "adjustAggregatedTimeRange" }, { kind: "pipe", type: ApplyRangeClassPipe, name: "applyRangeClass" }, { kind: "pipe", type: ColumnTitlePipe, name: "columnTitle" }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "component", type: i1$1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: i1$1.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i1$1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "directive", type: i1$1.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "pipe", type: i1$1.DatePipe, name: "c8yDate" }, { kind: "component", type: i1$1.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "ngmodule", type: DocsModule }, { kind: "directive", type: i1$1.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i1$1.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "directive", type: DynamicColumnDirective, selector: "[c8yDynamicColumn]", inputs: ["c8yDynamicColumn"] }, { kind: "ngmodule", type: DynamicComponentModule }, { kind: "component", type: i1$1.DynamicComponentAlertsComponent, selector: "c8y-dynamic-component-alerts", inputs: ["alerts"] }, { kind: "ngmodule", type: ListGroupModule }, { kind: "component", type: i1$1.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i1$1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i1$1.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i1$1.ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "directive", type: VirtualScrollListenerDirective, selector: "[c8yVirtualScrollListener]", inputs: ["scrollThreshold"], outputs: ["scrolled", "scrolledToTop"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1688
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: DatapointsTableComponent, isStandalone: true, selector: "c8y-datapoints-table", inputs: { aggregationType: "aggregationType", datapointsTableItems: "datapointsTableItems", devicesColumnHeaders: "devicesColumnHeaders", decimalPlaces: "decimalPlaces", hasMultipleDatapoints: "hasMultipleDatapoints", isLoading: "isLoading", seriesWithoutPermissionToReadCount: "seriesWithoutPermissionToReadCount" }, outputs: { isScrolling: "isScrolling" }, host: { classAttribute: "d-col flex-grow" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!hasNoPermissionsToReadAnyMeasurement; else missingAllPermissions\">\n <div class=\"c8y-cq-440\">\n <div\n class=\"hidden-xs c8y-list__item c8y-list--timeline hidden-cq\"\n [ngClass]=\"{ 'separator-top-bottom': devicesColumnHeaders.length > 0 }\"\n >\n <div class=\"d-flex container-fluid\">\n <div class=\"c8y-list--timeline__item__date\"></div>\n <div class=\"c8y-list__item__block flex-grow min-width-0\">\n <div class=\"c8y-list__item__body\">\n <div class=\"d-flex row\">\n <ng-container *ngIf=\"hasMultipleDatapoints\">\n <div\n class=\"min-width-0\"\n [title]=\"'Device' | translate\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n >\n <span class=\"text-medium text-truncate\">\n {{ 'Device' | translate }}\n </span>\n </div>\n </ng-container>\n <!-- Data points column headers -->\n <ng-container *ngFor=\"let header of devicesColumnHeaders\">\n <div\n class=\"min-width-0\"\n title=\"{{ header | columnTitle }}\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n >\n <span class=\"text-medium text-truncate\">\n {{ header.label }} {{ header.unit }}\n </span>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- The record list -->\n <ng-container *ngIf=\"!isLoading; else loading\">\n <ng-container *ngIf=\"datapointsTableItems.length; else emptyState\">\n <c8y-list-group\n class=\"p-t-8 flex-grow c8y-cq-440\"\n c8yVirtualScrollListener\n (scrolled)=\"onListScrolled()\"\n (scrolledToTop)=\"onListScrolledToTop()\"\n >\n <c8y-li-timeline\n *c8yFor=\"\n let tableItem of { data: datapointsTableItems, res: null };\n enableVirtualScroll: true;\n virtualScrollElementSize: 40;\n virtualScrollStrategy: 'fixed'\n \"\n >\n {{ tableItem.dateAndTime | c8yDate: 'mediumDate' }}\n {{\n tableItem.dateAndTime\n | c8yDate: 'mediumTime'\n | adjustAggregatedTimeRange: aggregationType\n }}\n <c8y-li>\n <c8y-li-body>\n <div class=\"d-flex row\">\n <div\n class=\"min-width-0\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngIf=\"devicesColumnHeaders.length > 1\"\n [attr.data-label]=\"'Device' | translate\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ tableItem.deviceName }}\"\n >\n {{ tableItem.deviceName }}\n </div>\n </div>\n <!-- Data point value row cells -->\n <ng-container *ngFor=\"let row of tableItem.rowItems\">\n <ng-container *ngIf=\"row !== null; else emptyRowContent\">\n <ng-container [ngSwitch]=\"row.renderType\">\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n *ngSwitchCase=\"'min'\"\n [attr.data-label]=\"row.label\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </div>\n </div>\n <div\n class=\"col-md-4\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n *ngSwitchCase=\"'max'\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </div>\n </div>\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngSwitchCase=\"'area'\"\n >\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n ...\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.max ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n </div>\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngSwitchDefault\n >\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #emptyRowContent>\n <div [c8yDynamicColumn]=\"devicesColumnHeaders.length\"></div>\n </ng-template>\n </ng-container>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n </c8y-list-group>\n </ng-container>\n </ng-container>\n</ng-container>\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n<ng-template #emptyState>\n <div class=\"p-relative p-l-24\">\n <c8y-ui-empty-state\n [icon]=\"'c8y-alert-idle'\"\n [title]=\"'No data to display.' | translate\"\n [horizontal]=\"true\"\n data-cy=\"datapoints-table-list--empty-state\"\n >\n <p c8y-guide-docs>\n <small translate>\n Find out more in the\n <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-table\">\n user documentation\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n </div>\n</ng-template>\n<ng-template #missingAllPermissions>\n <div class=\"p-t-24 p-r-16 p-l-16 p-b-16 d-flex\">\n <div class=\"center-block\">\n <c8y-dynamic-component-alerts\n [alerts]=\"missingAllPermissionsAlert\"\n ></c8y-dynamic-component-alerts>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "pipe", type: AdjustAggregatedTimeRangePipe, name: "adjustAggregatedTimeRange" }, { kind: "pipe", type: ApplyRangeClassPipe, name: "applyRangeClass" }, { kind: "pipe", type: ColumnTitlePipe, name: "columnTitle" }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "component", type: i1$1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: i1$1.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i1$1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "directive", type: i1$1.ForOfDirective, selector: "[c8yFor]", inputs: ["c8yForOf", "c8yForLoadMore", "c8yForPipe", "c8yForNotFound", "c8yForMaxIterations", "c8yForLoadingTemplate", "c8yForLoadNextLabel", "c8yForLoadingLabel", "c8yForRealtime", "c8yForRealtimeOptions", "c8yForComparator", "c8yForEnableVirtualScroll", "c8yForVirtualScrollElementSize", "c8yForVirtualScrollStrategy", "c8yForVirtualScrollContainerHeight"], outputs: ["c8yForCount", "c8yForChange", "c8yForLoadMoreComponent"] }, { kind: "pipe", type: i1$1.DatePipe, name: "c8yDate" }, { kind: "component", type: i1$1.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "ngmodule", type: DocsModule }, { kind: "directive", type: i1$1.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i1$1.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "directive", type: DynamicColumnDirective, selector: "[c8yDynamicColumn]", inputs: ["c8yDynamicColumn"] }, { kind: "ngmodule", type: DynamicComponentModule }, { kind: "component", type: i1$1.DynamicComponentAlertsComponent, selector: "c8y-dynamic-component-alerts", inputs: ["alerts"] }, { kind: "ngmodule", type: ListGroupModule }, { kind: "component", type: i1$1.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i1$1.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i1$1.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: i1$1.ListItemTimelineComponent, selector: "c8y-list-item-timeline, c8y-li-timeline" }, { kind: "directive", type: VirtualScrollListenerDirective, selector: "[c8yVirtualScrollListener]", inputs: ["scrollThreshold"], outputs: ["scrolled", "scrolledToTop"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1666
1689
|
}
|
|
1667
1690
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableComponent, decorators: [{
|
|
1668
1691
|
type: Component,
|
|
@@ -1676,7 +1699,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
|
|
|
1676
1699
|
DynamicComponentModule,
|
|
1677
1700
|
ListGroupModule,
|
|
1678
1701
|
VirtualScrollListenerDirective
|
|
1679
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"c8y-cq-440\">\n
|
|
1702
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"!hasNoPermissionsToReadAnyMeasurement; else missingAllPermissions\">\n <div class=\"c8y-cq-440\">\n <div\n class=\"hidden-xs c8y-list__item c8y-list--timeline hidden-cq\"\n [ngClass]=\"{ 'separator-top-bottom': devicesColumnHeaders.length > 0 }\"\n >\n <div class=\"d-flex container-fluid\">\n <div class=\"c8y-list--timeline__item__date\"></div>\n <div class=\"c8y-list__item__block flex-grow min-width-0\">\n <div class=\"c8y-list__item__body\">\n <div class=\"d-flex row\">\n <ng-container *ngIf=\"hasMultipleDatapoints\">\n <div\n class=\"min-width-0\"\n [title]=\"'Device' | translate\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n >\n <span class=\"text-medium text-truncate\">\n {{ 'Device' | translate }}\n </span>\n </div>\n </ng-container>\n <!-- Data points column headers -->\n <ng-container *ngFor=\"let header of devicesColumnHeaders\">\n <div\n class=\"min-width-0\"\n title=\"{{ header | columnTitle }}\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n >\n <span class=\"text-medium text-truncate\">\n {{ header.label }} {{ header.unit }}\n </span>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- The record list -->\n <ng-container *ngIf=\"!isLoading; else loading\">\n <ng-container *ngIf=\"datapointsTableItems.length; else emptyState\">\n <c8y-list-group\n class=\"p-t-8 flex-grow c8y-cq-440\"\n c8yVirtualScrollListener\n (scrolled)=\"onListScrolled()\"\n (scrolledToTop)=\"onListScrolledToTop()\"\n >\n <c8y-li-timeline\n *c8yFor=\"\n let tableItem of { data: datapointsTableItems, res: null };\n enableVirtualScroll: true;\n virtualScrollElementSize: 40;\n virtualScrollStrategy: 'fixed'\n \"\n >\n {{ tableItem.dateAndTime | c8yDate: 'mediumDate' }}\n {{\n tableItem.dateAndTime\n | c8yDate: 'mediumTime'\n | adjustAggregatedTimeRange: aggregationType\n }}\n <c8y-li>\n <c8y-li-body>\n <div class=\"d-flex row\">\n <div\n class=\"min-width-0\"\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngIf=\"devicesColumnHeaders.length > 1\"\n [attr.data-label]=\"'Device' | translate\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ tableItem.deviceName }}\"\n >\n {{ tableItem.deviceName }}\n </div>\n </div>\n <!-- Data point value row cells -->\n <ng-container *ngFor=\"let row of tableItem.rowItems\">\n <ng-container *ngIf=\"row !== null; else emptyRowContent\">\n <ng-container [ngSwitch]=\"row.renderType\">\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n *ngSwitchCase=\"'min'\"\n [attr.data-label]=\"row.label\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </div>\n </div>\n <div\n class=\"col-md-4\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n *ngSwitchCase=\"'max'\"\n >\n <div\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </div>\n </div>\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngSwitchCase=\"'area'\"\n >\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n ...\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.max ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n </div>\n <div\n [c8yDynamicColumn]=\"devicesColumnHeaders.length\"\n *ngSwitchDefault\n >\n <span\n class=\"text-truncate\"\n title=\"{{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\"\n [ngClass]=\"row.value.min ?? null | applyRangeClass: getRangeValues(row)\"\n >\n {{ row.value.min ?? '' | number: getFractionSize(row.value.min) }}\n </span>\n </div>\n </ng-container>\n </ng-container>\n <ng-template #emptyRowContent>\n <div [c8yDynamicColumn]=\"devicesColumnHeaders.length\"></div>\n </ng-template>\n </ng-container>\n </div>\n </c8y-li-body>\n </c8y-li>\n </c8y-li-timeline>\n </c8y-list-group>\n </ng-container>\n </ng-container>\n</ng-container>\n<ng-template #loading>\n <c8y-loading></c8y-loading>\n</ng-template>\n<ng-template #emptyState>\n <div class=\"p-relative p-l-24\">\n <c8y-ui-empty-state\n [icon]=\"'c8y-alert-idle'\"\n [title]=\"'No data to display.' | translate\"\n [horizontal]=\"true\"\n data-cy=\"datapoints-table-list--empty-state\"\n >\n <p c8y-guide-docs>\n <small translate>\n Find out more in the\n <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-table\">\n user documentation\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n </div>\n</ng-template>\n<ng-template #missingAllPermissions>\n <div class=\"p-t-24 p-r-16 p-l-16 p-b-16 d-flex\">\n <div class=\"center-block\">\n <c8y-dynamic-component-alerts\n [alerts]=\"missingAllPermissionsAlert\"\n ></c8y-dynamic-component-alerts>\n </div>\n </div>\n</ng-template>\n" }]
|
|
1680
1703
|
}], propDecorators: { aggregationType: [{
|
|
1681
1704
|
type: Input
|
|
1682
1705
|
}], datapointsTableItems: [{
|
|
@@ -1696,11 +1719,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
|
|
|
1696
1719
|
}] } });
|
|
1697
1720
|
|
|
1698
1721
|
class DatapointsTableViewWidgetComponent {
|
|
1699
|
-
constructor(datapointsTableConfigService, datapointsTableViewService, formBuilder, translateService) {
|
|
1722
|
+
constructor(alertService, dataFetchingService, datapointsTableConfigService, datapointsTableViewService, formBuilder, translateService, widgetGlobalAutoRefresh) {
|
|
1723
|
+
this.alertService = alertService;
|
|
1724
|
+
this.dataFetchingService = dataFetchingService;
|
|
1700
1725
|
this.datapointsTableConfigService = datapointsTableConfigService;
|
|
1701
1726
|
this.datapointsTableViewService = datapointsTableViewService;
|
|
1702
1727
|
this.formBuilder = formBuilder;
|
|
1703
1728
|
this.translateService = translateService;
|
|
1729
|
+
this.widgetGlobalAutoRefresh = widgetGlobalAutoRefresh;
|
|
1704
1730
|
/**
|
|
1705
1731
|
* Represents the data points where __active property is set to true.
|
|
1706
1732
|
*/
|
|
@@ -1710,7 +1736,11 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1710
1736
|
* Used to populate the table with data.
|
|
1711
1737
|
*/
|
|
1712
1738
|
this.datapointsTableItems = [];
|
|
1713
|
-
|
|
1739
|
+
/**
|
|
1740
|
+
* Indicates whether refreshing should be enabled or disabled.
|
|
1741
|
+
* It's 'true' when user is not allowed to view a measurements.
|
|
1742
|
+
*/
|
|
1743
|
+
this.isRefreshDisabled = false;
|
|
1714
1744
|
/**
|
|
1715
1745
|
* Indicates whether the component is in the initial request state
|
|
1716
1746
|
* where data for a table structure is being prepared.
|
|
@@ -1719,9 +1749,12 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1719
1749
|
/**
|
|
1720
1750
|
* Current isLoading state. Indicates whether the data is being loaded.
|
|
1721
1751
|
*/
|
|
1722
|
-
this.isLoading =
|
|
1752
|
+
this.isLoading$ = new BehaviorSubject(true);
|
|
1723
1753
|
this.isExportModalOpen = false;
|
|
1724
1754
|
this.isScrolling = signal(false);
|
|
1755
|
+
this.TIMEOUT_ERROR_TEXT = gettext('The request is taking longer than usual. We apologize for the inconvenience.');
|
|
1756
|
+
this.SERVER_ERROR_TEXT = gettext('Server error occurred.');
|
|
1757
|
+
this.destroy$ = new Subject();
|
|
1725
1758
|
this.scrollingSubject$ = new Subject();
|
|
1726
1759
|
/**
|
|
1727
1760
|
* Indicates if the alert has already been displayed and can be dismissed.
|
|
@@ -1730,19 +1763,27 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1730
1763
|
this.isMissingAnyPermissionAlertShown = false;
|
|
1731
1764
|
}
|
|
1732
1765
|
async ngOnInit() {
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1766
|
+
if (this.config.widgetInstanceGlobalAutoRefreshContext) {
|
|
1767
|
+
this.containerClass = 'a-i-center input-group p-t-4 p-b-4 max-width-fit m-l-auto';
|
|
1768
|
+
}
|
|
1769
|
+
/**
|
|
1770
|
+
* Legacy widget used realtime so it must be converted to refresh approach
|
|
1771
|
+
* if it was enabled before migration.
|
|
1772
|
+
*/
|
|
1738
1773
|
if (this.config.widgetInstanceGlobalTimeContext) {
|
|
1774
|
+
this.config.widgetInstanceGlobalAutoRefreshContext = true;
|
|
1739
1775
|
this.config.widgetInstanceGlobalTimeContext = false;
|
|
1776
|
+
this.config.displaySettings.globalAutoRefreshContext = true;
|
|
1777
|
+
}
|
|
1778
|
+
if (this.config.widgetInstanceGlobalAutoRefreshContext) {
|
|
1779
|
+
this.handleGlobalRefreshLoading();
|
|
1780
|
+
this.handleGlobalTimeContextSettings();
|
|
1740
1781
|
}
|
|
1741
1782
|
this.setScrollingSubscription();
|
|
1742
1783
|
const isLegacyWidgetRealtimeActive = this.config.realtime &&
|
|
1743
|
-
!this.config.decimalPlaces &&
|
|
1744
|
-
!this.config.refreshInterval &&
|
|
1745
|
-
!this.config.isAutoRefreshEnabled;
|
|
1784
|
+
!this.config.hasOwnProperty('decimalPlaces') &&
|
|
1785
|
+
!this.config.hasOwnProperty('refreshInterval') &&
|
|
1786
|
+
!this.config.hasOwnProperty('isAutoRefreshEnabled');
|
|
1746
1787
|
if (isLegacyWidgetRealtimeActive) {
|
|
1747
1788
|
this.setDefaultRefreshRelatedProperties();
|
|
1748
1789
|
}
|
|
@@ -1780,6 +1821,8 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1780
1821
|
if (this.subscription) {
|
|
1781
1822
|
this.subscription.unsubscribe();
|
|
1782
1823
|
}
|
|
1824
|
+
this.destroy$.next();
|
|
1825
|
+
this.destroy$.complete();
|
|
1783
1826
|
}
|
|
1784
1827
|
onDateChange(data) {
|
|
1785
1828
|
if (this.formGroup.invalid) {
|
|
@@ -1812,14 +1855,8 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1812
1855
|
this.onScrolling(false);
|
|
1813
1856
|
}
|
|
1814
1857
|
handleGlobalTimeContextSettings() {
|
|
1815
|
-
this.config.dateFrom = this.
|
|
1816
|
-
this.config.dateTo = this.
|
|
1817
|
-
if (this.config.realtime) {
|
|
1818
|
-
this.setDefaultRefreshRelatedProperties();
|
|
1819
|
-
}
|
|
1820
|
-
else {
|
|
1821
|
-
this.config.isAutoRefreshEnabled = false;
|
|
1822
|
-
}
|
|
1858
|
+
this.config.dateFrom = this.dataFetchingService.adjustDate(this.config.date[0], 0, false);
|
|
1859
|
+
this.config.dateTo = this.dataFetchingService.adjustDate(this.config.date[1], 0, false);
|
|
1823
1860
|
}
|
|
1824
1861
|
/**
|
|
1825
1862
|
* Sets up the scrolling subscription.
|
|
@@ -1836,7 +1873,7 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1836
1873
|
this.config.refreshInterval = DEFAULT_COUNTDOWN_VALUE;
|
|
1837
1874
|
}
|
|
1838
1875
|
recalculateIntervalToMatchFromNowDate() {
|
|
1839
|
-
if (this.config.
|
|
1876
|
+
if (this.config.widgetInstanceGlobalAutoRefreshContext) {
|
|
1840
1877
|
return;
|
|
1841
1878
|
}
|
|
1842
1879
|
const { dateFrom, dateTo } = this.datapointsTableConfigService.calculateDateRange(this.config.interval);
|
|
@@ -1868,7 +1905,7 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1868
1905
|
* If false, the seconds will be displayed as they are.
|
|
1869
1906
|
*/
|
|
1870
1907
|
async prepareTableData(roundSeconds = true) {
|
|
1871
|
-
this.isLoading
|
|
1908
|
+
this.isLoading$.next(true);
|
|
1872
1909
|
if (this.isInitialRequest) {
|
|
1873
1910
|
this.activeDatapoints = this.datapointsTableViewService.filterOutInactiveDatapoints(this.config.datapoints);
|
|
1874
1911
|
this.hasMultipleDatapoints = this.datapointsTableViewService.hasMultipleDatapoints(this.activeDatapoints);
|
|
@@ -1877,6 +1914,9 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1877
1914
|
}
|
|
1878
1915
|
const activeDatapointsIdsWithSeries = this.datapointsTableViewService.groupSeriesByDeviceId(this.activeDatapoints);
|
|
1879
1916
|
const activeDatapointsSeriesData = await this.getActiveDatapointsSeriesDataMap(activeDatapointsIdsWithSeries, this.config, roundSeconds);
|
|
1917
|
+
if (this.isFailedToFetchSeriesData) {
|
|
1918
|
+
return;
|
|
1919
|
+
}
|
|
1880
1920
|
this.seriesWithoutPermissionToRead =
|
|
1881
1921
|
this.datapointsTableViewService.getSeriesWithoutPermissionToRead(activeDatapointsSeriesData, activeDatapointsIdsWithSeries);
|
|
1882
1922
|
if (!this.isMissingAnyPermissionAlertShown &&
|
|
@@ -1892,7 +1932,7 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1892
1932
|
const datapointsListItems = this.datapointsTableViewService.mapDatapointsWithValuesToList(this.datapointsWithValues);
|
|
1893
1933
|
const groupedDatapointsListItems = this.datapointsTableViewService.groupByDateAndDevice(datapointsListItems, this.devicesColumnHeaders);
|
|
1894
1934
|
this.datapointsTableItems = this.datapointsTableViewService.sortDataByDateDescending(groupedDatapointsListItems);
|
|
1895
|
-
this.isLoading
|
|
1935
|
+
this.isLoading$.next(false);
|
|
1896
1936
|
}
|
|
1897
1937
|
/**
|
|
1898
1938
|
* Retrieves the active data points series data and returns it as a map.
|
|
@@ -1908,13 +1948,32 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1908
1948
|
*/
|
|
1909
1949
|
async getActiveDatapointsSeriesDataMap(datapointsIdsWithSeries, config, roundSeconds) {
|
|
1910
1950
|
try {
|
|
1951
|
+
this.isFailedToFetchSeriesData = false;
|
|
1911
1952
|
return await this.datapointsTableViewService.getAllActiveSeriesDataMap(datapointsIdsWithSeries, config, roundSeconds);
|
|
1912
1953
|
}
|
|
1913
1954
|
catch (error) {
|
|
1914
|
-
this.
|
|
1915
|
-
this.
|
|
1955
|
+
this.isLoading$.next(false);
|
|
1956
|
+
this.handleFetchError(error);
|
|
1916
1957
|
}
|
|
1917
1958
|
}
|
|
1959
|
+
handleFetchError(error) {
|
|
1960
|
+
if (error?.message.includes('403')) {
|
|
1961
|
+
this.alerts.setAlertGroupDismissStrategy('warning', DismissAlertStrategy.NONE);
|
|
1962
|
+
this.isRefreshDisabled = true;
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1965
|
+
const isTimeoutError = error?.name === 'TimeoutError';
|
|
1966
|
+
const errorMessage = isTimeoutError
|
|
1967
|
+
? this.TIMEOUT_ERROR_TEXT
|
|
1968
|
+
: error?.message ?? this.SERVER_ERROR_TEXT;
|
|
1969
|
+
this.alerts.setAlertGroupDismissStrategy('warning', DismissAlertStrategy.TEMPORARY_OR_PERMANENT);
|
|
1970
|
+
this.alerts.addAlerts(new DynamicComponentAlert({
|
|
1971
|
+
type: 'warning',
|
|
1972
|
+
text: errorMessage
|
|
1973
|
+
}));
|
|
1974
|
+
this.isFailedToFetchSeriesData = true;
|
|
1975
|
+
this.alertService.addServerFailure(error);
|
|
1976
|
+
}
|
|
1918
1977
|
handleMissingAnyPermissionErrorMessage() {
|
|
1919
1978
|
this.alerts.setAlertGroupDismissStrategy('system', DismissAlertStrategy.TEMPORARY);
|
|
1920
1979
|
this.alerts.addAlerts(new DynamicComponentAlert({
|
|
@@ -1938,11 +1997,16 @@ class DatapointsTableViewWidgetComponent {
|
|
|
1938
1997
|
</div>
|
|
1939
1998
|
`;
|
|
1940
1999
|
}
|
|
1941
|
-
|
|
1942
|
-
|
|
2000
|
+
handleGlobalRefreshLoading() {
|
|
2001
|
+
this.isLoading$
|
|
2002
|
+
.pipe(globalAutoRefreshLoading(this.widgetGlobalAutoRefresh), takeUntil(this.destroy$))
|
|
2003
|
+
.subscribe();
|
|
2004
|
+
}
|
|
2005
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableViewWidgetComponent, deps: [{ token: i1$1.AlertService }, { token: i2$1.DataFetchingService }, { token: DatapointsTableService }, { token: DatapointsTableViewService }, { token: i3.FormBuilder }, { token: i1$2.TranslateService }, { token: i1$1.WidgetGlobalAutoRefreshService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2006
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: DatapointsTableViewWidgetComponent, isStandalone: true, selector: "c8y-datapoints-table-view", inputs: { config: "config" }, host: { classAttribute: "d-col fit-h" }, ngImport: i0, template: "<div class=\"d-flex gap-16 p-l-16 p-r-16 flex-wrap\">\n <ng-container *ngIf=\"config.displayDateSelection\">\n <form [formGroup]=\"formGroup\">\n <c8y-date-range-picker\n class=\"d-contents\"\n [isEmittingDateChange]=\"true\"\n [showLabel]=\"true\"\n (updatedDate)=\"onDateChange($event)\"\n ></c8y-date-range-picker>\n </form>\n </ng-container>\n <!-- TODO: temporarily commented out, will be enabled when graft of MTM-59689 is merged: https://github.com/Cumulocity-IoT/cumulocity-ui/pull/8028 -->\n <!-- <c8y-datapoints-export-selector\n class=\"d-contents\"\n [containerClass]=\"containerClass\"\n [exportConfig]=\"exportConfig\"\n (isOpen)=\"onExportModalOpen($event)\"\n ></c8y-datapoints-export-selector> -->\n <!-- TODO: below div is just a temp fix, it will be removed when MTM-59689 is merged: https://github.com/Cumulocity-IoT/cumulocity-ui/pull/8028 -->\n <div class=\"input-group p-t-4 p-b-4 max-width-fit m-l-auto\"></div>\n <ng-container *ngIf=\"config.datapoints.length > 0\">\n <c8y-datapoints-reload\n class=\"d-contents\"\n [isAutoRefreshEnabled]=\"config.isAutoRefreshEnabled\"\n [refreshInterval]=\"config.refreshInterval\"\n [isRefreshDisabled]=\"isRefreshDisabled\"\n [isLoading]=\"isLoading$\"\n [isScrolling]=\"isScrolling()\"\n [isExportModalOpen]=\"isExportModalOpen\"\n [widgetInstanceGlobalAutoRefreshContext]=\"config.widgetInstanceGlobalAutoRefreshContext\"\n (onCountdownEnded)=\"onCountdownEnded()\"\n ></c8y-datapoints-reload>\n </ng-container>\n</div>\n<ng-container *ngIf=\"devicesColumnHeaders\">\n <c8y-datapoints-table\n [aggregationType]=\"config.aggregation\"\n [datapointsTableItems]=\"datapointsTableItems\"\n [decimalPlaces]=\"config.decimalPlaces\"\n [devicesColumnHeaders]=\"devicesColumnHeaders\"\n [hasMultipleDatapoints]=\"hasMultipleDatapoints\"\n [isLoading]=\"isLoading$ | async\"\n [seriesWithoutPermissionToReadCount]=\"seriesWithoutPermissionToRead?.length\"\n (isScrolling)=\"onScrolling($event)\"\n ></c8y-datapoints-table>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "component", type:
|
|
1943
2007
|
// TODO: temporarily commented out, will be enabled when MTM-59689 is integrated
|
|
1944
2008
|
// DatapointsExportSelectorComponent,
|
|
1945
|
-
DatapointsReloadComponent, selector: "c8y-datapoints-reload", inputs: ["isAutoRefreshEnabled", "
|
|
2009
|
+
DatapointsReloadComponent, selector: "c8y-datapoints-reload", inputs: ["isAutoRefreshEnabled", "isRefreshDisabled", "isLoading", "isScrolling", "isExportModalOpen", "refreshInterval", "widgetInstanceGlobalAutoRefreshContext"], outputs: ["onCountdownEnded"] }, { kind: "component", type: DatapointsTableComponent, selector: "c8y-datapoints-table", inputs: ["aggregationType", "datapointsTableItems", "devicesColumnHeaders", "decimalPlaces", "hasMultipleDatapoints", "isLoading", "seriesWithoutPermissionToReadCount"], outputs: ["isScrolling"] }, { kind: "component", type: DateRangePickerComponent, selector: "c8y-date-range-picker", inputs: ["isEmittingDateChange", "showLabel"], outputs: ["updatedDate"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
|
|
1946
2010
|
}
|
|
1947
2011
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DatapointsTableViewWidgetComponent, decorators: [{
|
|
1948
2012
|
type: Component,
|
|
@@ -1954,8 +2018,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImpor
|
|
|
1954
2018
|
DatapointsTableComponent,
|
|
1955
2019
|
DateRangePickerComponent,
|
|
1956
2020
|
ReactiveFormsModule
|
|
1957
|
-
], template: "<div class=\"d-flex gap-16 p-l-16 p-r-16 flex-wrap\">\n <ng-container *ngIf=\"config.displayDateSelection\">\n <form [formGroup]=\"formGroup\">\n <c8y-date-range-picker\n class=\"d-contents\"\n [isEmittingDateChange]=\"true\"\n [showLabel]=\"true\"\n (updatedDate)=\"onDateChange($event)\"\n ></c8y-date-range-picker>\n </form>\n </ng-container>\n <!-- TODO: temporarily commented out, will be enabled when MTM-59689 is
|
|
1958
|
-
}], ctorParameters: () => [{ type: DatapointsTableService }, { type: DatapointsTableViewService }, { type: i3.FormBuilder }, { type: i1$2.TranslateService }], propDecorators: { config: [{
|
|
2021
|
+
], template: "<div class=\"d-flex gap-16 p-l-16 p-r-16 flex-wrap\">\n <ng-container *ngIf=\"config.displayDateSelection\">\n <form [formGroup]=\"formGroup\">\n <c8y-date-range-picker\n class=\"d-contents\"\n [isEmittingDateChange]=\"true\"\n [showLabel]=\"true\"\n (updatedDate)=\"onDateChange($event)\"\n ></c8y-date-range-picker>\n </form>\n </ng-container>\n <!-- TODO: temporarily commented out, will be enabled when graft of MTM-59689 is merged: https://github.com/Cumulocity-IoT/cumulocity-ui/pull/8028 -->\n <!-- <c8y-datapoints-export-selector\n class=\"d-contents\"\n [containerClass]=\"containerClass\"\n [exportConfig]=\"exportConfig\"\n (isOpen)=\"onExportModalOpen($event)\"\n ></c8y-datapoints-export-selector> -->\n <!-- TODO: below div is just a temp fix, it will be removed when MTM-59689 is merged: https://github.com/Cumulocity-IoT/cumulocity-ui/pull/8028 -->\n <div class=\"input-group p-t-4 p-b-4 max-width-fit m-l-auto\"></div>\n <ng-container *ngIf=\"config.datapoints.length > 0\">\n <c8y-datapoints-reload\n class=\"d-contents\"\n [isAutoRefreshEnabled]=\"config.isAutoRefreshEnabled\"\n [refreshInterval]=\"config.refreshInterval\"\n [isRefreshDisabled]=\"isRefreshDisabled\"\n [isLoading]=\"isLoading$\"\n [isScrolling]=\"isScrolling()\"\n [isExportModalOpen]=\"isExportModalOpen\"\n [widgetInstanceGlobalAutoRefreshContext]=\"config.widgetInstanceGlobalAutoRefreshContext\"\n (onCountdownEnded)=\"onCountdownEnded()\"\n ></c8y-datapoints-reload>\n </ng-container>\n</div>\n<ng-container *ngIf=\"devicesColumnHeaders\">\n <c8y-datapoints-table\n [aggregationType]=\"config.aggregation\"\n [datapointsTableItems]=\"datapointsTableItems\"\n [decimalPlaces]=\"config.decimalPlaces\"\n [devicesColumnHeaders]=\"devicesColumnHeaders\"\n [hasMultipleDatapoints]=\"hasMultipleDatapoints\"\n [isLoading]=\"isLoading$ | async\"\n [seriesWithoutPermissionToReadCount]=\"seriesWithoutPermissionToRead?.length\"\n (isScrolling)=\"onScrolling($event)\"\n ></c8y-datapoints-table>\n</ng-container>\n" }]
|
|
2022
|
+
}], ctorParameters: () => [{ type: i1$1.AlertService }, { type: i2$1.DataFetchingService }, { type: DatapointsTableService }, { type: DatapointsTableViewService }, { type: i3.FormBuilder }, { type: i1$2.TranslateService }, { type: i1$1.WidgetGlobalAutoRefreshService }], propDecorators: { config: [{
|
|
1959
2023
|
type: Input
|
|
1960
2024
|
}] } });
|
|
1961
2025
|
|