@c8y/ngx-components 1024.1.8 → 1024.2.4
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/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +64 -25
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +363 -38
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart-models.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart.mjs +796 -123
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-global-context.mjs +391 -54
- package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-time-context.mjs +146 -20
- package/fesm2022/c8y-ngx-components-time-context.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs +198 -24
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +100 -32
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/de.po +80 -8
- package/locales/es.po +80 -8
- package/locales/fr.po +80 -8
- package/locales/ja_JP.po +80 -8
- package/locales/ko.po +80 -8
- package/locales/locales.pot +79 -7
- package/locales/nl.po +80 -8
- package/locales/pl.po +80 -8
- package/locales/pt_BR.po +80 -8
- package/locales/zh_CN.po +80 -8
- package/locales/zh_TW.po +80 -8
- package/package.json +1 -1
- package/types/c8y-ngx-components-datapoint-explorer-view.d.ts +4 -1
- package/types/c8y-ngx-components-datapoint-explorer-view.d.ts.map +1 -1
- package/types/c8y-ngx-components-datapoint-selector.d.ts +93 -5
- package/types/c8y-ngx-components-datapoint-selector.d.ts.map +1 -1
- package/types/c8y-ngx-components-echart-models.d.ts +25 -3
- package/types/c8y-ngx-components-echart-models.d.ts.map +1 -1
- package/types/c8y-ngx-components-echart.d.ts +65 -5
- package/types/c8y-ngx-components-echart.d.ts.map +1 -1
- package/types/c8y-ngx-components-global-context.d.ts +187 -7
- package/types/c8y-ngx-components-global-context.d.ts.map +1 -1
- package/types/c8y-ngx-components-time-context.d.ts +50 -8
- package/types/c8y-ngx-components-time-context.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-alarms.d.ts +1 -0
- package/types/c8y-ngx-components-widgets-implementations-alarms.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts +25 -0
- package/types/c8y-ngx-components-widgets-implementations-datapoints-graph.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-datapoints-list.d.ts +1 -0
- package/types/c8y-ngx-components-widgets-implementations-datapoints-list.d.ts.map +1 -1
- package/types/c8y-ngx-components-widgets-implementations-scada.d.ts +2 -0
- package/types/c8y-ngx-components-widgets-implementations-scada.d.ts.map +1 -1
- package/types/c8y-ngx-components.d.ts +50 -11
- package/types/c8y-ngx-components.d.ts.map +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { gettext } from '@c8y/ngx-components/gettext';
|
|
2
|
-
import { aggregationType } from '@c8y/client';
|
|
2
|
+
import { aggregationType, MeasurementService } from '@c8y/client';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { computed, signal, Injectable, inject, input, forwardRef, ChangeDetectionStrategy, Component, DestroyRef,
|
|
4
|
+
import { computed, signal, Injectable, inject, input, output, forwardRef, ChangeDetectionStrategy, Component, DestroyRef, Input, ChangeDetectorRef, ViewChild, EventEmitter, viewChild, effect, HostListener, Output, InjectionToken, TemplateRef, untracked, ContentChild, NgModule } from '@angular/core';
|
|
5
5
|
import * as i4 from '@c8y/ngx-components';
|
|
6
|
-
import { ViewContext, I18nModule, IconDirective, FormGroupComponent, MessagesComponent, MessageDirective, DateTimePickerModule, C8yTranslatePipe, DatePipe, TabsOutletComponent, FormsModule as FormsModule$1, CountdownIntervalModule, CountdownIntervalComponent, AlertService, ContextRouteService, DashboardChildComponent, hookActionBar } from '@c8y/ngx-components';
|
|
7
|
-
import { BehaviorSubject, map, distinctUntilChanged, shareReplay, fromEvent, filter, debounceTime, startWith, tap as tap$1, firstValueFrom, combineLatest, Subject, take, skip, throttleTime, merge as merge$1, EMPTY } from 'rxjs';
|
|
6
|
+
import { ViewContext, I18nModule, IconDirective, FormGroupComponent, MessagesComponent, MessageDirective, DateTimePickerModule, C8yTranslatePipe, DatePipe, TabsOutletComponent, FormsModule as FormsModule$1, AUTO_POINTS_TOOLTIP, AUTO_POINTS_TOOLTIP_KEPT, CountdownIntervalModule, CountdownIntervalComponent, AlertService, ContextRouteService, DashboardChildComponent, hookActionBar } from '@c8y/ngx-components';
|
|
7
|
+
import { BehaviorSubject, map, distinctUntilChanged, shareReplay, fromEvent, filter, debounce, timer, debounceTime, startWith, tap as tap$1, firstValueFrom, combineLatest, Subject, take, skip, throttleTime, merge as merge$1, EMPTY } from 'rxjs';
|
|
8
8
|
import * as i1 from '@angular/forms';
|
|
9
|
-
import { FormBuilder, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule, FormControl } from '@angular/forms';
|
|
9
|
+
import { FormBuilder, FormsModule, NG_VALUE_ACCESSOR, Validators, ReactiveFormsModule, FormControl } from '@angular/forms';
|
|
10
10
|
import { pick, omit, isObject, isEqual, transform, some, cloneDeep, merge, isEmpty } from 'lodash-es';
|
|
11
11
|
import { ActivatedRoute, Router, NavigationStart, NavigationEnd, ActivationEnd } from '@angular/router';
|
|
12
12
|
import * as i1$1 from '@angular/common';
|
|
@@ -17,7 +17,7 @@ import * as i2 from 'ngx-bootstrap/tooltip';
|
|
|
17
17
|
import { TooltipModule } from 'ngx-bootstrap/tooltip';
|
|
18
18
|
import * as i1$2 from 'ngx-bootstrap/collapse';
|
|
19
19
|
import { CollapseModule } from 'ngx-bootstrap/collapse';
|
|
20
|
-
import * as
|
|
20
|
+
import * as i3 from 'ngx-bootstrap/popover';
|
|
21
21
|
import { PopoverModule } from 'ngx-bootstrap/popover';
|
|
22
22
|
import * as i2$1 from 'ngx-bootstrap/dropdown';
|
|
23
23
|
import { BsDropdownModule, BsDropdownDirective } from 'ngx-bootstrap/dropdown';
|
|
@@ -189,8 +189,17 @@ const AGGREGATION_ICON_TYPE = {
|
|
|
189
189
|
UNDEFINED: 'line-chart',
|
|
190
190
|
MINUTELY: 'hourglass',
|
|
191
191
|
HOURLY: 'clock-o',
|
|
192
|
-
DAILY: 'calendar-o'
|
|
192
|
+
DAILY: 'calendar-o',
|
|
193
|
+
AUTO: 'automation'
|
|
193
194
|
};
|
|
195
|
+
/** Short label for the automatic aggregation mode — used as the picker option title. */
|
|
196
|
+
const AUTO_AGGREGATION_TEXT = gettext('Auto`automatic aggregation mode`');
|
|
197
|
+
/**
|
|
198
|
+
* Long label for the automatic aggregation mode — used where the current value is shown
|
|
199
|
+
* (picker tooltip, action-bar display) so it reads consistently alongside "Minutely
|
|
200
|
+
* aggregation", "Hourly aggregation", etc.
|
|
201
|
+
*/
|
|
202
|
+
const AUTO_AGGREGATION_TEXT_LONG = gettext('Automatic aggregation');
|
|
194
203
|
const AGGREGATION_ICONS = {
|
|
195
204
|
undefined: AGGREGATION_ICON_TYPE.UNDEFINED,
|
|
196
205
|
MINUTELY: AGGREGATION_ICON_TYPE.MINUTELY,
|
|
@@ -198,7 +207,7 @@ const AGGREGATION_ICONS = {
|
|
|
198
207
|
DAILY: AGGREGATION_ICON_TYPE.DAILY
|
|
199
208
|
};
|
|
200
209
|
const AGGREGATION_TEXTS = {
|
|
201
|
-
disabled: gettext('
|
|
210
|
+
disabled: gettext('Unavailable while real-time or auto-refresh is on.'),
|
|
202
211
|
undefined: gettext('No aggregation'),
|
|
203
212
|
null: gettext('No aggregation'),
|
|
204
213
|
MINUTELY: gettext('Minutely aggregation'),
|
|
@@ -224,6 +233,12 @@ const AGGREGATION_LABELS = {
|
|
|
224
233
|
[aggregationType.DAILY]: AGGREGATIONS[3].title
|
|
225
234
|
};
|
|
226
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Shared popover text explaining the aggregation control. Used by the history-mode
|
|
238
|
+
* configuration controls and the (legacy) time-context component so both stay in sync.
|
|
239
|
+
* "Auto" is intentionally not re-explained here — it has its own dedicated tooltip.
|
|
240
|
+
*/
|
|
241
|
+
const AGGREGATION_POPOVER_TEXT = gettext("Groups measurements into larger time intervals to improve readability and performance. 'None' shows raw data; other options group measurements into minute, hour, or day intervals.");
|
|
227
242
|
/**
|
|
228
243
|
* Time duration constants (ms)
|
|
229
244
|
*/
|
|
@@ -241,6 +256,8 @@ const TIME_DURATION = {
|
|
|
241
256
|
const TIMING = {
|
|
242
257
|
/** Debounce time for form value changes (ms) */
|
|
243
258
|
FORM_DEBOUNCE: 100,
|
|
259
|
+
/** Debounce time while the user is typing into a text/number field (ms) */
|
|
260
|
+
TYPING_DEBOUNCE: 500,
|
|
244
261
|
/** Throttle time for context changes (ms) */
|
|
245
262
|
CONTEXT_THROTTLE: 200,
|
|
246
263
|
/** Tooltip delay time (ms) */
|
|
@@ -255,6 +272,20 @@ const UI_PRIORITIES = {
|
|
|
255
272
|
/** High priority for configuration controls */
|
|
256
273
|
CONFIGURATION_PRIORITY: 1000
|
|
257
274
|
};
|
|
275
|
+
/**
|
|
276
|
+
* Bounds for the auto-aggregation "Datapoints target" control (how many buckets the auto
|
|
277
|
+
* interval aims for). Shared by the slider, the number input, and the clamping/validation logic.
|
|
278
|
+
*/
|
|
279
|
+
const AUTO_AGGREGATION_DATAPOINTS = {
|
|
280
|
+
/** Minimum number of target datapoints. */
|
|
281
|
+
MIN: 2,
|
|
282
|
+
/** Maximum number of target datapoints. */
|
|
283
|
+
MAX: 2000,
|
|
284
|
+
/** Increment for slider and number stepper. Must divide MAX - MIN so the slider reaches MAX. */
|
|
285
|
+
STEP: 1,
|
|
286
|
+
/** Default target when auto mode is enabled. */
|
|
287
|
+
DEFAULT: 300
|
|
288
|
+
};
|
|
258
289
|
|
|
259
290
|
/**
|
|
260
291
|
* Central utility for all DateTimeContext operations.
|
|
@@ -2722,6 +2753,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
2722
2753
|
}]
|
|
2723
2754
|
}] });
|
|
2724
2755
|
|
|
2756
|
+
/**
|
|
2757
|
+
* Detects whether the current tenant has been migrated to the time series measurement store.
|
|
2758
|
+
*
|
|
2759
|
+
* The automatic ("Auto") aggregation mode relies on `aggregationInterval` support, which is
|
|
2760
|
+
* only available on time-series-migrated tenants, so UI controls offering it must be hidden
|
|
2761
|
+
* on non-migrated tenants.
|
|
2762
|
+
*
|
|
2763
|
+
* @deprecated The detection itself is a workaround: the measurement detail endpoint responds
|
|
2764
|
+
* with 405 on migrated tenants because it is disabled there. To be replaced when the platform
|
|
2765
|
+
* exposes a proper way to identify time series migration (same approach as
|
|
2766
|
+
* `WidgetDatapointsSelectorComponent.detectTimeSeriesMigration`).
|
|
2767
|
+
*/
|
|
2768
|
+
class TimeSeriesMigrationService {
|
|
2769
|
+
constructor() {
|
|
2770
|
+
this.measurementService = inject(MeasurementService);
|
|
2771
|
+
this.migrationCheck = null;
|
|
2772
|
+
}
|
|
2773
|
+
/**
|
|
2774
|
+
* Resolves to `true` when the tenant is migrated to time series.
|
|
2775
|
+
* The result is cached for the lifetime of the application, as migration
|
|
2776
|
+
* state cannot change within a session.
|
|
2777
|
+
*/
|
|
2778
|
+
isTimeSeriesMigrated() {
|
|
2779
|
+
if (!this.migrationCheck) {
|
|
2780
|
+
this.migrationCheck = this.detectMigration();
|
|
2781
|
+
}
|
|
2782
|
+
return this.migrationCheck;
|
|
2783
|
+
}
|
|
2784
|
+
async detectMigration() {
|
|
2785
|
+
try {
|
|
2786
|
+
// Any id works: on migrated tenants the endpoint itself is disabled and returns 405.
|
|
2787
|
+
await this.measurementService.detail(1);
|
|
2788
|
+
return false;
|
|
2789
|
+
}
|
|
2790
|
+
catch (err) {
|
|
2791
|
+
return err?.res?.status === 405;
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TimeSeriesMigrationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2795
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TimeSeriesMigrationService, providedIn: 'root' }); }
|
|
2796
|
+
}
|
|
2797
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TimeSeriesMigrationService, decorators: [{
|
|
2798
|
+
type: Injectable,
|
|
2799
|
+
args: [{ providedIn: 'root' }]
|
|
2800
|
+
}] });
|
|
2801
|
+
|
|
2725
2802
|
class GlobalContextUtilsService {
|
|
2726
2803
|
/**
|
|
2727
2804
|
* Compares two objects and returns an object containing only the fields that changed.
|
|
@@ -2825,6 +2902,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
2825
2902
|
}]
|
|
2826
2903
|
}] });
|
|
2827
2904
|
|
|
2905
|
+
const AUTO_AGGREGATION_ID = 'AUTO';
|
|
2906
|
+
const AUTO_ITEM = { id: AUTO_AGGREGATION_ID, title: AUTO_AGGREGATION_TEXT };
|
|
2828
2907
|
class AggregationPickerComponent {
|
|
2829
2908
|
constructor() {
|
|
2830
2909
|
/**
|
|
@@ -2845,10 +2924,31 @@ class AggregationPickerComponent {
|
|
|
2845
2924
|
* Default is dropdown.
|
|
2846
2925
|
*/
|
|
2847
2926
|
this.layout = input('dropdown', ...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
2927
|
+
/**
|
|
2928
|
+
* When true, appends an "Auto" option to the radio group that signals automatic
|
|
2929
|
+
* aggregation selection. Use together with `autoModeActive` and `(autoModeChange)`.
|
|
2930
|
+
* Only meaningful in radio layout.
|
|
2931
|
+
*/
|
|
2932
|
+
this.showAutoMode = input(false, ...(ngDevMode ? [{ debugName: "showAutoMode" }] : /* istanbul ignore next */ []));
|
|
2933
|
+
/**
|
|
2934
|
+
* Controls whether the "Auto" radio option appears checked.
|
|
2935
|
+
* Bind to your form's auto-mode boolean so the picker reflects external state.
|
|
2936
|
+
*/
|
|
2937
|
+
this.autoModeActive = input(false, ...(ngDevMode ? [{ debugName: "autoModeActive" }] : /* istanbul ignore next */ []));
|
|
2938
|
+
/**
|
|
2939
|
+
* When true, the "Auto" option is rendered but disabled (greyed out). Use for widgets that show
|
|
2940
|
+
* the option for discoverability but do not support auto mode (only the Data graph does).
|
|
2941
|
+
*/
|
|
2942
|
+
this.autoModeDisabled = input(false, ...(ngDevMode ? [{ debugName: "autoModeDisabled" }] : /* istanbul ignore next */ []));
|
|
2943
|
+
/** Emits `true` when the user selects "Auto", `false` when switching away from it. */
|
|
2944
|
+
this.autoModeChange = output();
|
|
2848
2945
|
this._disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
|
|
2849
2946
|
this.disabled = computed(() => this._disabled(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
2850
2947
|
this.AGGREGATIONS = AGGREGATIONS;
|
|
2948
|
+
this.AUTO_ITEM_ID = AUTO_AGGREGATION_ID;
|
|
2949
|
+
this.AVAILABLE_AGGREGATIONS = computed(() => this.showAutoMode() ? [...AGGREGATIONS, AUTO_ITEM] : AGGREGATIONS, ...(ngDevMode ? [{ debugName: "AVAILABLE_AGGREGATIONS" }] : /* istanbul ignore next */ []));
|
|
2851
2950
|
this.AGGREGATION_ICONS = AGGREGATION_ICONS;
|
|
2951
|
+
this.AUTO_ICON = AGGREGATION_ICON_TYPE.AUTO;
|
|
2852
2952
|
this.AGGREGATION_TEXTS = AGGREGATION_TEXTS;
|
|
2853
2953
|
this._value = signal(null, ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
2854
2954
|
this.value = computed(() => this._value(), ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
@@ -2856,13 +2956,20 @@ class AggregationPickerComponent {
|
|
|
2856
2956
|
this.touched = computed(() => this._touched(), ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
|
|
2857
2957
|
// Computed helpers for cleaner templates
|
|
2858
2958
|
this.currentText = computed(() => {
|
|
2959
|
+
if (this.autoModeActive()) {
|
|
2960
|
+
return AUTO_AGGREGATION_TEXT_LONG;
|
|
2961
|
+
}
|
|
2859
2962
|
const value = this._value();
|
|
2860
2963
|
return value ? this.AGGREGATION_TEXTS[value] : this.AGGREGATION_TEXTS.undefined;
|
|
2861
2964
|
}, ...(ngDevMode ? [{ debugName: "currentText" }] : /* istanbul ignore next */ []));
|
|
2862
2965
|
this.currentIcon = computed(() => {
|
|
2966
|
+
if (this.autoModeActive()) {
|
|
2967
|
+
return AGGREGATION_ICON_TYPE.AUTO;
|
|
2968
|
+
}
|
|
2863
2969
|
const value = this._value();
|
|
2864
2970
|
return value ? this.AGGREGATION_ICONS[value] : this.AGGREGATION_ICONS.undefined;
|
|
2865
2971
|
}, ...(ngDevMode ? [{ debugName: "currentIcon" }] : /* istanbul ignore next */ []));
|
|
2972
|
+
this.AUTO_MODE_TOOLTIP = gettext('Auto picks an aggregation interval from the time range and the aggregation points per chart you set. Available only for the Data graph widget.');
|
|
2866
2973
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2867
2974
|
this.onChange = _ => { };
|
|
2868
2975
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
@@ -2893,13 +3000,33 @@ class AggregationPickerComponent {
|
|
|
2893
3000
|
}
|
|
2894
3001
|
}
|
|
2895
3002
|
selectAggregation(aggregation) {
|
|
2896
|
-
|
|
2897
|
-
|
|
3003
|
+
const isAuto = aggregation === AUTO_AGGREGATION_ID;
|
|
3004
|
+
// Early return: Auto is disabled for this widget
|
|
3005
|
+
if (isAuto && this.autoModeDisabled()) {
|
|
3006
|
+
return;
|
|
3007
|
+
}
|
|
3008
|
+
// Early return: clicking Auto when already in auto mode
|
|
3009
|
+
if (isAuto && this.autoModeActive()) {
|
|
3010
|
+
return;
|
|
3011
|
+
}
|
|
3012
|
+
// Early return: clicking the same non-auto aggregation when not in auto mode
|
|
3013
|
+
if (!isAuto && !this.autoModeActive() && aggregation === this._value()) {
|
|
2898
3014
|
return;
|
|
2899
3015
|
}
|
|
2900
3016
|
this.markAsTouched();
|
|
2901
|
-
this.
|
|
2902
|
-
|
|
3017
|
+
const wasAuto = this.autoModeActive();
|
|
3018
|
+
if (isAuto) {
|
|
3019
|
+
this._value.set(null);
|
|
3020
|
+
this.onChange(null);
|
|
3021
|
+
this.autoModeChange.emit(true);
|
|
3022
|
+
}
|
|
3023
|
+
else {
|
|
3024
|
+
this._value.set(aggregation);
|
|
3025
|
+
this.onChange(aggregation);
|
|
3026
|
+
if (wasAuto) {
|
|
3027
|
+
this.autoModeChange.emit(false);
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
2903
3030
|
}
|
|
2904
3031
|
resetValue() {
|
|
2905
3032
|
if (this._value() !== null) {
|
|
@@ -2908,13 +3035,13 @@ class AggregationPickerComponent {
|
|
|
2908
3035
|
}
|
|
2909
3036
|
}
|
|
2910
3037
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AggregationPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2911
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: AggregationPickerComponent, isStandalone: true, selector: "c8y-aggregation-picker", inputs: { disabledAggregations: { classPropertyName: "disabledAggregations", publicName: "disabledAggregations", isSignal: true, isRequired: false, transformFunction: null }, resetToDefault: { classPropertyName: "resetToDefault", publicName: "resetToDefault", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
3038
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: AggregationPickerComponent, isStandalone: true, selector: "c8y-aggregation-picker", inputs: { disabledAggregations: { classPropertyName: "disabledAggregations", publicName: "disabledAggregations", isSignal: true, isRequired: false, transformFunction: null }, resetToDefault: { classPropertyName: "resetToDefault", publicName: "resetToDefault", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, showAutoMode: { classPropertyName: "showAutoMode", publicName: "showAutoMode", isSignal: true, isRequired: false, transformFunction: null }, autoModeActive: { classPropertyName: "autoModeActive", publicName: "autoModeActive", isSignal: true, isRequired: false, transformFunction: null }, autoModeDisabled: { classPropertyName: "autoModeDisabled", publicName: "autoModeDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { autoModeChange: "autoModeChange" }, providers: [
|
|
2912
3039
|
{
|
|
2913
3040
|
provide: NG_VALUE_ACCESSOR,
|
|
2914
3041
|
useExisting: forwardRef(() => AggregationPickerComponent),
|
|
2915
3042
|
multi: true
|
|
2916
3043
|
}
|
|
2917
|
-
], ngImport: i0, template: "@if (layout() === 'dropdown') {\n <div\n class=\"dropdown\"\n style=\"border: 0; margin-left: -1px\"\n container=\"body\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [attr.data-cy]=\"'global-context--aggregation-picker'\"\n [insideClick]=\"true\"\n [isDisabled]=\"disabled()\"\n >\n <button\n class=\"dropdown-toggle form-control p-t-0 p-b-0 l-h-1 d-flex a-i-center\"\n [attr.aria-label]=\"currentText() | translate\"\n tooltip=\"{{ (disabled() ? AGGREGATION_TEXTS.disabled : currentText()) | translate }}\"\n placement=\"top\"\n container=\"body\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"dropdown.isOpen\"\n type=\"button\"\n [attr.data-cy]=\"'global-context--aggregation-picker-' + value()\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"currentIcon()\"\n ></i>\n <span class=\"caret m-r-8 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-right--xs\"\n role=\"listbox\"\n *dropdownMenu\n >\n @for (aggregation of
|
|
3044
|
+
], ngImport: i0, template: "@if (layout() === 'dropdown') {\n <div\n class=\"dropdown\"\n style=\"border: 0; margin-left: -1px\"\n container=\"body\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [attr.data-cy]=\"'global-context--aggregation-picker'\"\n [insideClick]=\"true\"\n [isDisabled]=\"disabled()\"\n >\n <button\n class=\"dropdown-toggle form-control p-t-0 p-b-0 l-h-1 d-flex a-i-center\"\n [attr.aria-label]=\"currentText() | translate\"\n tooltip=\"{{ (disabled() ? AGGREGATION_TEXTS.disabled : currentText()) | translate }}\"\n placement=\"top\"\n container=\"body\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"dropdown.isOpen\"\n type=\"button\"\n [attr.data-cy]=\"'global-context--aggregation-picker-' + value()\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"currentIcon()\"\n ></i>\n <span class=\"caret m-r-8 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-right--xs\"\n role=\"listbox\"\n *dropdownMenu\n >\n @for (aggregation of AVAILABLE_AGGREGATIONS(); track aggregation.id || $index) {\n @let isAutoItem = aggregation.id === AUTO_ITEM_ID;\n @let isDisabled =\n isAutoItem\n ? autoModeDisabled()\n : aggregation.id\n ? disabledAggregations()[aggregation.id]\n : false;\n <li\n [class.active]=\"\n isAutoItem ? autoModeActive() : !autoModeActive() && aggregation.id === value()\n \"\n [class.disabled]=\"isDisabled\"\n >\n <button\n class=\"\"\n [attr.aria-selected]=\"\n isAutoItem ? autoModeActive() : !autoModeActive() && aggregation.id === value()\n \"\n role=\"option\"\n (click)=\"selectAggregation(aggregation.id); dropdown.isOpen = false\"\n [disabled]=\"isDisabled\"\n [attr.data-cy]=\"'global-context--aggregation-picker-input-' + aggregation.id\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n isAutoItem\n ? AUTO_ICON\n : aggregation.id\n ? AGGREGATION_ICONS[aggregation.id]\n : AGGREGATION_ICONS.undefined\n \"\n ></i>\n <span>{{ aggregation.title | translate }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n}\n\n@if (layout() === 'radio') {\n <div\n class=\"radio-group d-flex-md a-i-center gap-16\"\n [class.flex-wrap]=\"showAutoMode()\"\n [attr.aria-label]=\"'Aggregation options' | translate\"\n role=\"radiogroup\"\n >\n @for (aggregation of AVAILABLE_AGGREGATIONS(); track aggregation.id || $index) {\n @let isAutoItem = aggregation.id === AUTO_ITEM_ID;\n @let isDisabled =\n isAutoItem\n ? autoModeDisabled()\n : aggregation.id\n ? disabledAggregations()[aggregation.id]\n : false;\n @let isChecked =\n isAutoItem ? autoModeActive() : !autoModeActive() && aggregation.id === value();\n <label\n class=\"c8y-radio\"\n [class.disabled]=\"isDisabled\"\n [attr.data-cy]=\"'global-context--aggregation-picker-input-' + aggregation.id\"\n >\n <input\n name=\"aggregation\"\n role=\"radio\"\n type=\"radio\"\n [value]=\"aggregation.id\"\n [checked]=\"isChecked\"\n [disabled]=\"isDisabled\"\n (change)=\"selectAggregation(aggregation.id)\"\n />\n <span></span>\n <i\n class=\"icon-16 m-l-4\"\n [c8yIcon]=\"\n isAutoItem\n ? AUTO_ICON\n : aggregation.id\n ? AGGREGATION_ICONS[aggregation.id]\n : AGGREGATION_ICONS.undefined\n \"\n aria-hidden=\"true\"\n ></i>\n <span>{{ aggregation.title | translate }}</span>\n @if (isAutoItem) {\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AUTO_MODE_TOOLTIP | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </label>\n }\n\n @if (showAutoMode() && autoModeActive()) {\n <ng-content select=\"[autoAggregationOptions]\"></ng-content>\n }\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i2$1.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i2$1.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i2$1.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "ngmodule", type: I18nModule }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i3.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i4.C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2918
3045
|
}
|
|
2919
3046
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AggregationPickerComponent, decorators: [{
|
|
2920
3047
|
type: Component,
|
|
@@ -2924,8 +3051,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
2924
3051
|
useExisting: forwardRef(() => AggregationPickerComponent),
|
|
2925
3052
|
multi: true
|
|
2926
3053
|
}
|
|
2927
|
-
], standalone: true, imports: [TooltipModule, BsDropdownModule, I18nModule, IconDirective, FormsModule], template: "@if (layout() === 'dropdown') {\n <div\n class=\"dropdown\"\n style=\"border: 0; margin-left: -1px\"\n container=\"body\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [attr.data-cy]=\"'global-context--aggregation-picker'\"\n [insideClick]=\"true\"\n [isDisabled]=\"disabled()\"\n >\n <button\n class=\"dropdown-toggle form-control p-t-0 p-b-0 l-h-1 d-flex a-i-center\"\n [attr.aria-label]=\"currentText() | translate\"\n tooltip=\"{{ (disabled() ? AGGREGATION_TEXTS.disabled : currentText()) | translate }}\"\n placement=\"top\"\n container=\"body\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"dropdown.isOpen\"\n type=\"button\"\n [attr.data-cy]=\"'global-context--aggregation-picker-' + value()\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"currentIcon()\"\n ></i>\n <span class=\"caret m-r-8 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-right--xs\"\n role=\"listbox\"\n *dropdownMenu\n >\n @for (aggregation of
|
|
2928
|
-
}], propDecorators: { disabledAggregations: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledAggregations", required: false }] }], resetToDefault: [{ type: i0.Input, args: [{ isSignal: true, alias: "resetToDefault", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }] } });
|
|
3054
|
+
], standalone: true, imports: [TooltipModule, BsDropdownModule, I18nModule, IconDirective, FormsModule, PopoverModule], template: "@if (layout() === 'dropdown') {\n <div\n class=\"dropdown\"\n style=\"border: 0; margin-left: -1px\"\n container=\"body\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [attr.data-cy]=\"'global-context--aggregation-picker'\"\n [insideClick]=\"true\"\n [isDisabled]=\"disabled()\"\n >\n <button\n class=\"dropdown-toggle form-control p-t-0 p-b-0 l-h-1 d-flex a-i-center\"\n [attr.aria-label]=\"currentText() | translate\"\n tooltip=\"{{ (disabled() ? AGGREGATION_TEXTS.disabled : currentText()) | translate }}\"\n placement=\"top\"\n container=\"body\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"dropdown.isOpen\"\n type=\"button\"\n [attr.data-cy]=\"'global-context--aggregation-picker-' + value()\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"currentIcon()\"\n ></i>\n <span class=\"caret m-r-8 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-right--xs\"\n role=\"listbox\"\n *dropdownMenu\n >\n @for (aggregation of AVAILABLE_AGGREGATIONS(); track aggregation.id || $index) {\n @let isAutoItem = aggregation.id === AUTO_ITEM_ID;\n @let isDisabled =\n isAutoItem\n ? autoModeDisabled()\n : aggregation.id\n ? disabledAggregations()[aggregation.id]\n : false;\n <li\n [class.active]=\"\n isAutoItem ? autoModeActive() : !autoModeActive() && aggregation.id === value()\n \"\n [class.disabled]=\"isDisabled\"\n >\n <button\n class=\"\"\n [attr.aria-selected]=\"\n isAutoItem ? autoModeActive() : !autoModeActive() && aggregation.id === value()\n \"\n role=\"option\"\n (click)=\"selectAggregation(aggregation.id); dropdown.isOpen = false\"\n [disabled]=\"isDisabled\"\n [attr.data-cy]=\"'global-context--aggregation-picker-input-' + aggregation.id\"\n >\n <i\n class=\"icon-14\"\n [c8yIcon]=\"\n isAutoItem\n ? AUTO_ICON\n : aggregation.id\n ? AGGREGATION_ICONS[aggregation.id]\n : AGGREGATION_ICONS.undefined\n \"\n ></i>\n <span>{{ aggregation.title | translate }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n}\n\n@if (layout() === 'radio') {\n <div\n class=\"radio-group d-flex-md a-i-center gap-16\"\n [class.flex-wrap]=\"showAutoMode()\"\n [attr.aria-label]=\"'Aggregation options' | translate\"\n role=\"radiogroup\"\n >\n @for (aggregation of AVAILABLE_AGGREGATIONS(); track aggregation.id || $index) {\n @let isAutoItem = aggregation.id === AUTO_ITEM_ID;\n @let isDisabled =\n isAutoItem\n ? autoModeDisabled()\n : aggregation.id\n ? disabledAggregations()[aggregation.id]\n : false;\n @let isChecked =\n isAutoItem ? autoModeActive() : !autoModeActive() && aggregation.id === value();\n <label\n class=\"c8y-radio\"\n [class.disabled]=\"isDisabled\"\n [attr.data-cy]=\"'global-context--aggregation-picker-input-' + aggregation.id\"\n >\n <input\n name=\"aggregation\"\n role=\"radio\"\n type=\"radio\"\n [value]=\"aggregation.id\"\n [checked]=\"isChecked\"\n [disabled]=\"isDisabled\"\n (change)=\"selectAggregation(aggregation.id)\"\n />\n <span></span>\n <i\n class=\"icon-16 m-l-4\"\n [c8yIcon]=\"\n isAutoItem\n ? AUTO_ICON\n : aggregation.id\n ? AGGREGATION_ICONS[aggregation.id]\n : AGGREGATION_ICONS.undefined\n \"\n aria-hidden=\"true\"\n ></i>\n <span>{{ aggregation.title | translate }}</span>\n @if (isAutoItem) {\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AUTO_MODE_TOOLTIP | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n }\n </label>\n }\n\n @if (showAutoMode() && autoModeActive()) {\n <ng-content select=\"[autoAggregationOptions]\"></ng-content>\n }\n </div>\n}\n" }]
|
|
3055
|
+
}], propDecorators: { disabledAggregations: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledAggregations", required: false }] }], resetToDefault: [{ type: i0.Input, args: [{ isSignal: true, alias: "resetToDefault", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], showAutoMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAutoMode", required: false }] }], autoModeActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoModeActive", required: false }] }], autoModeDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoModeDisabled", required: false }] }], autoModeChange: [{ type: i0.Output, args: ["autoModeChange"] }] } });
|
|
2929
3056
|
|
|
2930
3057
|
/**
|
|
2931
3058
|
* Component for configuring history mode settings
|
|
@@ -2956,6 +3083,7 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
2956
3083
|
constructor() {
|
|
2957
3084
|
this.AGGREGATION_TEXTS = AGGREGATION_TEXTS;
|
|
2958
3085
|
this.DATE_FORMAT = 'medium';
|
|
3086
|
+
this.AUTO_AGGREGATION_DATAPOINTS = AUTO_AGGREGATION_DATAPOINTS;
|
|
2959
3087
|
this.errorMessages = {
|
|
2960
3088
|
dateAfterRangeMax: gettext('This date is after the latest allowed date.'),
|
|
2961
3089
|
dateBeforeRangeMin: gettext('This date is before the earliest allowed date.'),
|
|
@@ -2964,10 +3092,11 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
2964
3092
|
};
|
|
2965
3093
|
// Popover messages for translation extraction
|
|
2966
3094
|
this.TIME_RANGE_PICKER_POPOVER = gettext('Specify the exact start and end date/time of the time period to analyse. This provides a static view of historical data within the selected timeframe.');
|
|
2967
|
-
this.AGGREGATION_POPOVER =
|
|
3095
|
+
this.AGGREGATION_POPOVER = AGGREGATION_POPOVER_TEXT;
|
|
2968
3096
|
this.destroyRef = inject(DestroyRef);
|
|
2969
3097
|
this.formBuilder = inject(FormBuilder);
|
|
2970
3098
|
this.aggregationPickerService = inject(AggregationPickerService);
|
|
3099
|
+
this.timeSeriesMigrationService = inject(TimeSeriesMigrationService);
|
|
2971
3100
|
this.settingsSignal = signal({
|
|
2972
3101
|
showAutoRefresh: true,
|
|
2973
3102
|
showTimeContext: true,
|
|
@@ -2979,14 +3108,35 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
2979
3108
|
this.disabledAggregations = signal({}, ...(ngDevMode ? [{ debugName: "disabledAggregations" }] : /* istanbul ignore next */ []));
|
|
2980
3109
|
this.dateFromErrors = signal(null, ...(ngDevMode ? [{ debugName: "dateFromErrors" }] : /* istanbul ignore next */ []));
|
|
2981
3110
|
this.dateToErrors = signal(null, ...(ngDevMode ? [{ debugName: "dateToErrors" }] : /* istanbul ignore next */ []));
|
|
3111
|
+
/** Whether auto-aggregation mode is active. */
|
|
3112
|
+
this.isAutoModeActive = signal(false, ...(ngDevMode ? [{ debugName: "isAutoModeActive" }] : /* istanbul ignore next */ []));
|
|
3113
|
+
/** Whether the "Auto" option should be shown but disabled (greyed) for the current widget. */
|
|
3114
|
+
this.autoModeDisabled = computed(() => !!this.settingsSignal().autoModeDisabled, ...(ngDevMode ? [{ debugName: "autoModeDisabled" }] : /* istanbul ignore next */ []));
|
|
3115
|
+
/**
|
|
3116
|
+
* The "Auto" option requires the tenant to be migrated to time series
|
|
3117
|
+
* (auto mode uses `aggregationInterval`, unsupported on non-migrated tenants).
|
|
3118
|
+
*/
|
|
3119
|
+
this.isTimeSeriesMigrated = signal(false, ...(ngDevMode ? [{ debugName: "isTimeSeriesMigrated" }] : /* istanbul ignore next */ []));
|
|
3120
|
+
/** Popover text for the "Keep point count on zoom" checkbox. */
|
|
3121
|
+
this.KEEP_DATA_ON_ZOOM_IN_POPOVER = gettext('When enabled, the chart reloads data at a finer or coarser interval as you zoom in or out, so it always shows the number of points you set. When disabled, it reuses the already loaded data.');
|
|
2982
3122
|
this.currentForm = this.createForm();
|
|
3123
|
+
this.lastProcessedFormValue = this.currentForm.value;
|
|
3124
|
+
this.timeSeriesMigrationService
|
|
3125
|
+
.isTimeSeriesMigrated()
|
|
3126
|
+
.then(isMigrated => this.isTimeSeriesMigrated.set(isMigrated));
|
|
2983
3127
|
this.currentForm.valueChanges
|
|
2984
|
-
.pipe(takeUntilDestroyed(this.destroyRef),
|
|
3128
|
+
.pipe(takeUntilDestroyed(this.destroyRef),
|
|
3129
|
+
// Typing into the datapoints number field gets a longer debounce so the context (and
|
|
3130
|
+
// the charts consuming it) does not refresh on every keystroke.
|
|
3131
|
+
debounce(formValue => timer(this.isDatapointsOnlyChange(formValue)
|
|
3132
|
+
? TIMING.TYPING_DEBOUNCE
|
|
3133
|
+
: TIMING.FORM_DEBOUNCE)))
|
|
2985
3134
|
.subscribe(formValue => {
|
|
2986
3135
|
this.handleFormValueChange(formValue);
|
|
3136
|
+
this.lastProcessedFormValue = this.currentForm.value;
|
|
2987
3137
|
});
|
|
2988
3138
|
this.currentForm.statusChanges
|
|
2989
|
-
.pipe(takeUntilDestroyed(this.destroyRef), debounceTime(
|
|
3139
|
+
.pipe(takeUntilDestroyed(this.destroyRef), debounceTime(TIMING.FORM_DEBOUNCE))
|
|
2990
3140
|
.subscribe(() => {
|
|
2991
3141
|
this.updateErrorSignals();
|
|
2992
3142
|
this.validationStatus.emit(this.currentForm.valid);
|
|
@@ -2994,11 +3144,47 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
2994
3144
|
this.updateErrorSignals();
|
|
2995
3145
|
this.validationStatus.emit(this.currentForm.valid);
|
|
2996
3146
|
}
|
|
3147
|
+
/** Called by the aggregation picker's (autoModeChange) output. */
|
|
3148
|
+
onAutoModeChange(isAuto) {
|
|
3149
|
+
this.currentForm.patchValue({ autoAggregationEnabled: isAuto });
|
|
3150
|
+
this.isAutoModeActive.set(isAuto);
|
|
3151
|
+
}
|
|
2997
3152
|
setDateToNow() {
|
|
2998
3153
|
const now = new Date();
|
|
2999
3154
|
now.setSeconds(0, 0);
|
|
3000
3155
|
this.currentForm.get('dateTimeContext')?.get('dateTo')?.setValue(now.toISOString());
|
|
3001
3156
|
}
|
|
3157
|
+
/**
|
|
3158
|
+
* Commits a valid "Points per chart" value when the user leaves the field: snaps
|
|
3159
|
+
* an out-of-range number back into [MIN, MAX], and restores the last applied value when the
|
|
3160
|
+
* field was left empty. Called on the number input's change/blur — while typing, invalid or
|
|
3161
|
+
* empty values are simply not emitted (see handleFormValueChange).
|
|
3162
|
+
*/
|
|
3163
|
+
clampDatapoints() {
|
|
3164
|
+
const control = this.currentForm.get('autoAggregationDatapoints');
|
|
3165
|
+
const value = control?.value;
|
|
3166
|
+
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
3167
|
+
const lastApplied = this.contextState()?.autoAggregation?.datapoints ?? AUTO_AGGREGATION_DATAPOINTS.DEFAULT;
|
|
3168
|
+
control?.setValue(this.clampToDatapointsBounds(lastApplied));
|
|
3169
|
+
return;
|
|
3170
|
+
}
|
|
3171
|
+
const clamped = this.clampToDatapointsBounds(value);
|
|
3172
|
+
if (clamped !== value) {
|
|
3173
|
+
control?.setValue(clamped);
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
clampToDatapointsBounds(value) {
|
|
3177
|
+
return Math.min(AUTO_AGGREGATION_DATAPOINTS.MAX, Math.max(AUTO_AGGREGATION_DATAPOINTS.MIN, value));
|
|
3178
|
+
}
|
|
3179
|
+
/**
|
|
3180
|
+
* Whether `formValue` differs from the last processed form value only in the
|
|
3181
|
+
* `autoAggregationDatapoints` field, i.e. the user is typing into the datapoints input.
|
|
3182
|
+
*/
|
|
3183
|
+
isDatapointsOnlyChange(formValue) {
|
|
3184
|
+
const previous = this.lastProcessedFormValue;
|
|
3185
|
+
return (formValue.autoAggregationDatapoints !== previous.autoAggregationDatapoints &&
|
|
3186
|
+
isEqual({ ...formValue, autoAggregationDatapoints: null }, { ...previous, autoAggregationDatapoints: null }));
|
|
3187
|
+
}
|
|
3002
3188
|
updateErrorSignals() {
|
|
3003
3189
|
const dateTimeContext = this.currentForm?.get('dateTimeContext');
|
|
3004
3190
|
const dateFromControl = dateTimeContext?.get('dateFrom');
|
|
@@ -3018,7 +3204,7 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
3018
3204
|
this.dateToErrors.set(Object.keys(dateToControlErrors).length > 0 ? dateToControlErrors : null);
|
|
3019
3205
|
}
|
|
3020
3206
|
handleFormValueChange(formValue) {
|
|
3021
|
-
const { dateTimeContext, aggregation } = formValue;
|
|
3207
|
+
const { dateTimeContext, aggregation, autoAggregationEnabled, autoAggregationDatapoints, autoAggregationKeepDataOnZoomIn } = formValue;
|
|
3022
3208
|
if (!dateTimeContext) {
|
|
3023
3209
|
return;
|
|
3024
3210
|
}
|
|
@@ -3032,18 +3218,37 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
3032
3218
|
// Calculate disabled aggregations regardless of validation
|
|
3033
3219
|
// This allows us to disable aggregations even for edge cases like dateFrom === dateTo
|
|
3034
3220
|
dateTimeContext.interval = TIME_INTERVAL.CUSTOM;
|
|
3035
|
-
const { selectedAggregation, disabledAggregations } = this.aggregationPickerService.calculateAggregation([new Date(dateTimeContext.dateFrom), new Date(dateTimeContext.dateTo)], aggregation ?? null);
|
|
3221
|
+
const { selectedAggregation, disabledAggregations } = this.aggregationPickerService.calculateAggregation([new Date(dateTimeContext.dateFrom), new Date(dateTimeContext.dateTo)], autoAggregationEnabled ? null : (aggregation ?? null));
|
|
3036
3222
|
this.disabledAggregations.set(disabledAggregations);
|
|
3037
3223
|
// Skip emission if validation fails (e.g., dateFrom > dateTo), but still update UI
|
|
3038
3224
|
if (!this.isValidDateTimeContext(dateTimeContext)) {
|
|
3039
3225
|
return;
|
|
3040
3226
|
}
|
|
3041
|
-
if (
|
|
3227
|
+
if (autoAggregationEnabled && !this.isValidDatapoints(autoAggregationDatapoints)) {
|
|
3228
|
+
return;
|
|
3229
|
+
}
|
|
3230
|
+
// Only auto-update the standard aggregation when not in auto mode
|
|
3231
|
+
if (!autoAggregationEnabled && selectedAggregation !== undefined) {
|
|
3042
3232
|
this.currentForm.patchValue({ aggregation: selectedAggregation }, { emitEvent: false });
|
|
3043
3233
|
}
|
|
3044
|
-
const emission =
|
|
3234
|
+
const emission = {
|
|
3235
|
+
dateTimeContext: structuredClone(dateTimeContext),
|
|
3236
|
+
aggregation: autoAggregationEnabled ? null : (this.currentForm.value.aggregation ?? null),
|
|
3237
|
+
autoAggregation: autoAggregationEnabled
|
|
3238
|
+
? {
|
|
3239
|
+
datapoints: autoAggregationDatapoints,
|
|
3240
|
+
keepDataOnZoomIn: autoAggregationKeepDataOnZoomIn ?? true
|
|
3241
|
+
}
|
|
3242
|
+
: null
|
|
3243
|
+
};
|
|
3045
3244
|
this.contextChange.emit(emission);
|
|
3046
3245
|
}
|
|
3246
|
+
isValidDatapoints(value) {
|
|
3247
|
+
return (typeof value === 'number' &&
|
|
3248
|
+
!Number.isNaN(value) &&
|
|
3249
|
+
value >= AUTO_AGGREGATION_DATAPOINTS.MIN &&
|
|
3250
|
+
value <= AUTO_AGGREGATION_DATAPOINTS.MAX);
|
|
3251
|
+
}
|
|
3047
3252
|
isValidDateTimeContext(dateTimeContext) {
|
|
3048
3253
|
if (!dateTimeContext) {
|
|
3049
3254
|
return false;
|
|
@@ -3067,8 +3272,12 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
3067
3272
|
dateFrom: defaults.dateFrom,
|
|
3068
3273
|
dateTo: defaults.dateTo
|
|
3069
3274
|
},
|
|
3070
|
-
aggregation: null
|
|
3275
|
+
aggregation: null,
|
|
3276
|
+
autoAggregationEnabled: false,
|
|
3277
|
+
autoAggregationDatapoints: AUTO_AGGREGATION_DATAPOINTS.DEFAULT,
|
|
3278
|
+
autoAggregationKeepDataOnZoomIn: true
|
|
3071
3279
|
}, { emitEvent: false });
|
|
3280
|
+
this.lastProcessedFormValue = this.currentForm.value;
|
|
3072
3281
|
this.disabledAggregations.set({});
|
|
3073
3282
|
this.validationStatus.emit(this.currentForm.valid);
|
|
3074
3283
|
return;
|
|
@@ -3094,10 +3303,15 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
3094
3303
|
clonedContext.dateTo = normalizedTo.toISOString();
|
|
3095
3304
|
this.currentForm.patchValue({
|
|
3096
3305
|
dateTimeContext: clonedContext,
|
|
3097
|
-
aggregation: ctx.aggregation ?? null
|
|
3306
|
+
aggregation: ctx.autoAggregation ? null : (ctx.aggregation ?? null),
|
|
3307
|
+
autoAggregationEnabled: !!ctx.autoAggregation,
|
|
3308
|
+
autoAggregationDatapoints: this.clampToDatapointsBounds(ctx.autoAggregation?.datapoints ?? AUTO_AGGREGATION_DATAPOINTS.DEFAULT),
|
|
3309
|
+
autoAggregationKeepDataOnZoomIn: ctx.autoAggregation?.keepDataOnZoomIn ?? true
|
|
3098
3310
|
}, { emitEvent: false });
|
|
3311
|
+
this.lastProcessedFormValue = this.currentForm.value;
|
|
3312
|
+
this.isAutoModeActive.set(!!ctx.autoAggregation);
|
|
3099
3313
|
// Update disabled aggregations but DON'T override the value
|
|
3100
|
-
const { disabledAggregations } = this.aggregationPickerService.calculateAggregation([new Date(clonedContext.dateFrom), new Date(clonedContext.dateTo)], ctx.aggregation ?? null);
|
|
3314
|
+
const { disabledAggregations } = this.aggregationPickerService.calculateAggregation([new Date(clonedContext.dateFrom), new Date(clonedContext.dateTo)], ctx.autoAggregation ? null : (ctx.aggregation ?? null));
|
|
3101
3315
|
this.disabledAggregations.set(disabledAggregations);
|
|
3102
3316
|
this.validationStatus.emit(this.currentForm.valid);
|
|
3103
3317
|
}
|
|
@@ -3112,7 +3326,13 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
3112
3326
|
});
|
|
3113
3327
|
return this.formBuilder.group({
|
|
3114
3328
|
dateTimeContext,
|
|
3115
|
-
aggregation: this.formBuilder.control(null)
|
|
3329
|
+
aggregation: this.formBuilder.control(null),
|
|
3330
|
+
autoAggregationEnabled: this.formBuilder.control(false),
|
|
3331
|
+
autoAggregationDatapoints: this.formBuilder.control(AUTO_AGGREGATION_DATAPOINTS.DEFAULT, [
|
|
3332
|
+
Validators.min(AUTO_AGGREGATION_DATAPOINTS.MIN),
|
|
3333
|
+
Validators.max(AUTO_AGGREGATION_DATAPOINTS.MAX)
|
|
3334
|
+
]),
|
|
3335
|
+
autoAggregationKeepDataOnZoomIn: this.formBuilder.control(true)
|
|
3116
3336
|
});
|
|
3117
3337
|
}
|
|
3118
3338
|
getDefaultDateRange() {
|
|
@@ -3143,7 +3363,7 @@ class HistoryModeConfigurationControlsComponent {
|
|
|
3143
3363
|
};
|
|
3144
3364
|
}
|
|
3145
3365
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: HistoryModeConfigurationControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3146
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: HistoryModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-history-mode-configuration-controls", inputs: { settings: "settings", context: "context" }, outputs: { contextChange: "contextChange", validationStatus: "validationStatus" }, ngImport: i0, template: "@if (currentForm) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n\n <form [formGroup]=\"currentForm\">\n <div class=\"content-flex-100\">\n <div\n class=\"col-4\"\n [ngClass]=\"{ 'm-b-8': !SHOW_AGGREGATION }\"\n >\n @if (SHOW_TIME_CONTEXT) {\n @let dateTimeContext = currentForm.get('dateTimeContext');\n @let tempDateFromValue = dateTimeContext.get('dateFrom')?.value;\n @let tempDateToValue = dateTimeContext.get('dateTo')?.value;\n @let fromErrors = dateFromErrors();\n @let toErrors = dateToErrors();\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i\n class=\"\"\n [c8yIcon]=\"'calendar'\"\n ></i>\n </div>\n {{ 'Date & time range' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"content-flex-58 d-flex a-i-center m-b-0 p-t-16\">\n <c8y-form-group\n [class.has-error]=\"fromErrors\"\n class=\"form-group-sm d-flex a-i-center col-5 flex-wrap\"\n >\n <label\n class=\"m-b-sm-0 m-r-8 text-nowrap\"\n style=\"min-width: 30px\"\n [title]=\"'From`date`' | translate\"\n for=\"dateFrom\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"fromErrors\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToValue\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateFrom')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"fromErrors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateRange\"\n [text]=\"errorMessages.invalidDateRange | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [class.has-error]=\"toErrors\"\n class=\"form-group-sm d-flex flex-wrap col-7 a-i-center\"\n >\n <label\n class=\"m-b-sm-0 text-nowrap m-r-8\"\n style=\"min-width: 30px\"\n [title]=\"'To`date`' | translate\"\n for=\"dateTo\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"toErrors\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromValue\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateTo')\"\n ></c8y-date-time-picker>\n <button\n class=\"btn btn-sm btn-default m-l-4\"\n [title]=\"'Set to current time' | translate\"\n type=\"button\"\n (click)=\"setDateToNow()\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"'clock-o'\"\n ></i>\n {{ 'Now' | translate }}\n </button>\n <c8y-messages [show]=\"toErrors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"errorMessages.dateBeforeRangeMin | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-\">\n @if (SHOW_AGGREGATION) {\n @let selectedAggregation = currentForm.get('aggregation')?.value;\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item aggregation m-r-4\">\n <i [c8yIcon]=\"'input'\"></i>\n </div>\n {{ 'Aggregation' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AGGREGATION_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"p-t-16 p-b-16 m-b-4\">\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n [disabledAggregations]=\"disabledAggregations()\"\n [layout]=\"'radio'\"\n ></c8y-aggregation-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: I18nModule }, { kind: "directive", type: i4.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i2$2.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "component", type: i4.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3366
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: HistoryModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-history-mode-configuration-controls", inputs: { settings: "settings", context: "context" }, outputs: { contextChange: "contextChange", validationStatus: "validationStatus" }, ngImport: i0, template: "@if (currentForm) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n\n <form [formGroup]=\"currentForm\">\n <div class=\"content-flex-100\">\n <div\n class=\"col-4\"\n [ngClass]=\"{ 'm-b-8': !SHOW_AGGREGATION }\"\n >\n @if (SHOW_TIME_CONTEXT) {\n @let dateTimeContext = currentForm.get('dateTimeContext');\n @let tempDateFromValue = dateTimeContext.get('dateFrom')?.value;\n @let tempDateToValue = dateTimeContext.get('dateTo')?.value;\n @let fromErrors = dateFromErrors();\n @let toErrors = dateToErrors();\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i\n class=\"\"\n [c8yIcon]=\"'calendar'\"\n ></i>\n </div>\n {{ 'Date & time range' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"content-flex-58 d-flex a-i-center m-b-0 p-t-16\">\n <c8y-form-group\n [class.has-error]=\"fromErrors\"\n class=\"form-group-sm d-flex a-i-center col-5 flex-wrap\"\n >\n <label\n class=\"m-b-sm-0 m-r-8 text-nowrap\"\n style=\"min-width: 30px\"\n [title]=\"'From`date`' | translate\"\n for=\"dateFrom\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"fromErrors\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToValue\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateFrom')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"fromErrors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateRange\"\n [text]=\"errorMessages.invalidDateRange | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [class.has-error]=\"toErrors\"\n class=\"form-group-sm d-flex col-7 a-i-center\"\n >\n <label\n class=\"m-b-sm-0 text-nowrap m-r-8\"\n style=\"min-width: 30px\"\n [title]=\"'To`date`' | translate\"\n for=\"dateTo\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"toErrors\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromValue\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateTo')\"\n ></c8y-date-time-picker>\n <button\n class=\"btn btn-sm btn-default m-l-4\"\n [title]=\"'Set to current time' | translate\"\n type=\"button\"\n (click)=\"setDateToNow()\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"'clock-o'\"\n ></i>\n {{ 'Now' | translate }}\n </button>\n <c8y-messages [show]=\"toErrors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"errorMessages.dateBeforeRangeMin | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-8\">\n @if (SHOW_AGGREGATION) {\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item aggregation m-r-4\">\n <i [c8yIcon]=\"'input'\"></i>\n </div>\n {{ 'Aggregation' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AGGREGATION_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n\n <c8y-form-group class=\"p-t-16 m-b-4 p-b-16\">\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [layout]=\"'radio'\"\n [resetToDefault]=\"true\"\n [showAutoMode]=\"isTimeSeriesMigrated()\"\n [autoModeActive]=\"isAutoModeActive()\"\n [autoModeDisabled]=\"autoModeDisabled()\"\n [disabledAggregations]=\"disabledAggregations()\"\n (autoModeChange)=\"onAutoModeChange($event)\"\n >\n <div\n class=\"d-flex a-i-center gap-16 flex-wrap\"\n autoAggregationOptions\n >\n <div class=\"d-flex a-i-center\">\n <label\n class=\"m-b-0 m-r-8 text-nowrap\"\n for=\"autoAggregationDatapoints\"\n >\n {{ 'Points per chart' | translate }}\n </label>\n @let datapointsRangeText =\n 'Enter a value between {{ min }} and {{ max }}.'\n | translate\n : {\n min: AUTO_AGGREGATION_DATAPOINTS.MIN,\n max: AUTO_AGGREGATION_DATAPOINTS.MAX\n };\n <c8y-form-group class=\"form-group-sm m-b-0\">\n <input\n class=\"form-control input-sm\"\n style=\"width: 60px\"\n [attr.title]=\"datapointsRangeText\"\n [attr.aria-label]=\"'Points per chart' | translate\"\n id=\"autoAggregationDatapoints\"\n type=\"number\"\n [min]=\"AUTO_AGGREGATION_DATAPOINTS.MIN\"\n [max]=\"AUTO_AGGREGATION_DATAPOINTS.MAX\"\n [step]=\"AUTO_AGGREGATION_DATAPOINTS.STEP\"\n [formControl]=\"currentForm.controls.autoAggregationDatapoints\"\n (change)=\"clampDatapoints()\"\n data-cy=\"global-context--auto-aggregation-datapoints-input\"\n />\n @let datapointsErrors = currentForm.get('autoAggregationDatapoints')?.errors;\n <c8y-messages\n class=\"m-t-4\"\n [show]=\"datapointsErrors\"\n >\n <c8y-message\n name=\"min\"\n [text]=\"datapointsRangeText\"\n ></c8y-message>\n <c8y-message\n name=\"max\"\n [text]=\"datapointsRangeText\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <label\n class=\"c8y-switch m-b-0\"\n [title]=\"'Keep point count on zoom' | translate\"\n >\n <input\n type=\"checkbox\"\n [formControl]=\"currentForm.controls.autoAggregationKeepDataOnZoomIn\"\n data-cy=\"global-context--auto-aggregation-keep-data-on-zoom-in\"\n />\n <span></span>\n <span>{{ 'Keep point count on zoom' | translate }}</span>\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"KEEP_DATA_ON_ZOOM_IN_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n </div>\n </c8y-aggregation-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: I18nModule }, { kind: "directive", type: i4.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i3.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "component", type: i4.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout", "showAutoMode", "autoModeActive", "autoModeDisabled"], outputs: ["autoModeChange"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3147
3367
|
}
|
|
3148
3368
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: HistoryModeConfigurationControlsComponent, decorators: [{
|
|
3149
3369
|
type: Component,
|
|
@@ -3156,12 +3376,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
3156
3376
|
FormsModule,
|
|
3157
3377
|
PopoverModule,
|
|
3158
3378
|
FormGroupComponent,
|
|
3159
|
-
AggregationPickerComponent,
|
|
3160
3379
|
MessagesComponent,
|
|
3161
3380
|
MessageDirective,
|
|
3162
3381
|
DateTimePickerModule,
|
|
3163
|
-
NgClass
|
|
3164
|
-
|
|
3382
|
+
NgClass,
|
|
3383
|
+
AggregationPickerComponent
|
|
3384
|
+
], template: "@if (currentForm) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n\n <form [formGroup]=\"currentForm\">\n <div class=\"content-flex-100\">\n <div\n class=\"col-4\"\n [ngClass]=\"{ 'm-b-8': !SHOW_AGGREGATION }\"\n >\n @if (SHOW_TIME_CONTEXT) {\n @let dateTimeContext = currentForm.get('dateTimeContext');\n @let tempDateFromValue = dateTimeContext.get('dateFrom')?.value;\n @let tempDateToValue = dateTimeContext.get('dateTo')?.value;\n @let fromErrors = dateFromErrors();\n @let toErrors = dateToErrors();\n\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i\n class=\"\"\n [c8yIcon]=\"'calendar'\"\n ></i>\n </div>\n {{ 'Date & time range' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n <c8y-form-group class=\"content-flex-58 d-flex a-i-center m-b-0 p-t-16\">\n <c8y-form-group\n [class.has-error]=\"fromErrors\"\n class=\"form-group-sm d-flex a-i-center col-5 flex-wrap\"\n >\n <label\n class=\"m-b-sm-0 m-r-8 text-nowrap\"\n style=\"min-width: 30px\"\n [title]=\"'From`date`' | translate\"\n for=\"dateFrom\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"fromErrors\"\n id=\"dateFrom\"\n [maxDate]=\"tempDateToValue\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateFrom')\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"fromErrors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"errorMessages.dateAfterRangeMax | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateRange\"\n [text]=\"errorMessages.invalidDateRange | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [class.has-error]=\"toErrors\"\n class=\"form-group-sm d-flex col-7 a-i-center\"\n >\n <label\n class=\"m-b-sm-0 text-nowrap m-r-8\"\n style=\"min-width: 30px\"\n [title]=\"'To`date`' | translate\"\n for=\"dateTo\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n [class.has-error]=\"toErrors\"\n id=\"dateTo\"\n [minDate]=\"tempDateFromValue\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"dateTimeContext.get('dateTo')\"\n ></c8y-date-time-picker>\n <button\n class=\"btn btn-sm btn-default m-l-4\"\n [title]=\"'Set to current time' | translate\"\n type=\"button\"\n (click)=\"setDateToNow()\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"'clock-o'\"\n ></i>\n {{ 'Now' | translate }}\n </button>\n <c8y-messages [show]=\"toErrors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"errorMessages.dateBeforeRangeMin | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"errorMessages.invalidDateTime | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-8\">\n @if (SHOW_AGGREGATION) {\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item aggregation m-r-4\">\n <i [c8yIcon]=\"'input'\"></i>\n </div>\n {{ 'Aggregation' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"AGGREGATION_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </legend>\n\n <c8y-form-group class=\"p-t-16 m-b-4 p-b-16\">\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [layout]=\"'radio'\"\n [resetToDefault]=\"true\"\n [showAutoMode]=\"isTimeSeriesMigrated()\"\n [autoModeActive]=\"isAutoModeActive()\"\n [autoModeDisabled]=\"autoModeDisabled()\"\n [disabledAggregations]=\"disabledAggregations()\"\n (autoModeChange)=\"onAutoModeChange($event)\"\n >\n <div\n class=\"d-flex a-i-center gap-16 flex-wrap\"\n autoAggregationOptions\n >\n <div class=\"d-flex a-i-center\">\n <label\n class=\"m-b-0 m-r-8 text-nowrap\"\n for=\"autoAggregationDatapoints\"\n >\n {{ 'Points per chart' | translate }}\n </label>\n @let datapointsRangeText =\n 'Enter a value between {{ min }} and {{ max }}.'\n | translate\n : {\n min: AUTO_AGGREGATION_DATAPOINTS.MIN,\n max: AUTO_AGGREGATION_DATAPOINTS.MAX\n };\n <c8y-form-group class=\"form-group-sm m-b-0\">\n <input\n class=\"form-control input-sm\"\n style=\"width: 60px\"\n [attr.title]=\"datapointsRangeText\"\n [attr.aria-label]=\"'Points per chart' | translate\"\n id=\"autoAggregationDatapoints\"\n type=\"number\"\n [min]=\"AUTO_AGGREGATION_DATAPOINTS.MIN\"\n [max]=\"AUTO_AGGREGATION_DATAPOINTS.MAX\"\n [step]=\"AUTO_AGGREGATION_DATAPOINTS.STEP\"\n [formControl]=\"currentForm.controls.autoAggregationDatapoints\"\n (change)=\"clampDatapoints()\"\n data-cy=\"global-context--auto-aggregation-datapoints-input\"\n />\n @let datapointsErrors = currentForm.get('autoAggregationDatapoints')?.errors;\n <c8y-messages\n class=\"m-t-4\"\n [show]=\"datapointsErrors\"\n >\n <c8y-message\n name=\"min\"\n [text]=\"datapointsRangeText\"\n ></c8y-message>\n <c8y-message\n name=\"max\"\n [text]=\"datapointsRangeText\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <label\n class=\"c8y-switch m-b-0\"\n [title]=\"'Keep point count on zoom' | translate\"\n >\n <input\n type=\"checkbox\"\n [formControl]=\"currentForm.controls.autoAggregationKeepDataOnZoomIn\"\n data-cy=\"global-context--auto-aggregation-keep-data-on-zoom-in\"\n />\n <span></span>\n <span>{{ 'Keep point count on zoom' | translate }}</span>\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"KEEP_DATA_ON_ZOOM_IN_POPOVER | translate\"\n placement=\"top\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n </div>\n </c8y-aggregation-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n" }]
|
|
3165
3385
|
}], ctorParameters: () => [], propDecorators: { settings: [{
|
|
3166
3386
|
type: Input
|
|
3167
3387
|
}], context: [{
|
|
@@ -3618,7 +3838,7 @@ class LiveModeConfigurationControlsComponent {
|
|
|
3618
3838
|
}, { emitEvent: false });
|
|
3619
3839
|
}
|
|
3620
3840
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: LiveModeConfigurationControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3621
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: LiveModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-live-mode-configuration-controls", inputs: { settings: "settings", intervalOptions: "intervalOptions", context: "context" }, outputs: { contextChange: "contextChange" }, ngImport: i0, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n\n <form [formGroup]=\"form\">\n <div class=\"content-flex-82\">\n <div class=\"col-5\">\n @if (SHOW_TIME_CONTEXT) {\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i [c8yIcon]=\"'calendar'\"></i>\n </div>\n {{ 'Date & time' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\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-4 p-t-16 p-b-16\">\n <c8y-date-time-context-picker\n formControlName=\"dateTimeContext\"\n [config]=\"{ showDateTo: false, showDateFrom: true }\"\n [intervalOptions]=\"intervalOptions\"\n ></c8y-date-time-context-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-3\">\n @if (SHOW_AUTO_REFRESH) {\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex\">\n <div class=\"standalone btn-icon-dot__item auto-refresh m-r-4\">\n <i [c8yIcon]=\"'refresh'\"></i>\n </div>\n {{ 'Auto refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"REFRESH_POPOVER_MESSAGE | translate\"\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-8 form-group-sm p-t-16 p-b-16\">\n <div class=\"d-flex gap-8 a-i-center\">\n <label class=\"c8y-switch c8y-switch--inline\">\n <input\n type=\"checkbox\"\n #arInput\n formControlName=\"isAutoRefreshEnabled\"\n />\n <span></span>\n <span>\n {{ 'Auto refresh enabled' | translate }}\n </span>\n </label>\n </div>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type:
|
|
3841
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: LiveModeConfigurationControlsComponent, isStandalone: true, selector: "c8y-live-mode-configuration-controls", inputs: { settings: "settings", intervalOptions: "intervalOptions", context: "context" }, outputs: { contextChange: "contextChange" }, ngImport: i0, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n\n <form [formGroup]=\"form\">\n <div class=\"content-flex-82\">\n <div class=\"col-5\">\n @if (SHOW_TIME_CONTEXT) {\n <fieldset class=\"c8y-fieldset\">\n <legend>\n <div class=\"standalone btn-icon-dot__item time-context m-r-4\">\n <i [c8yIcon]=\"'calendar'\"></i>\n </div>\n {{ 'Date & time' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"TIME_RANGE_PICKER_POPOVER | translate\"\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-4 p-t-16 p-b-16\">\n <c8y-date-time-context-picker\n formControlName=\"dateTimeContext\"\n [config]=\"{ showDateTo: false, showDateFrom: true }\"\n [intervalOptions]=\"intervalOptions\"\n ></c8y-date-time-context-picker>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n <div class=\"col-3\">\n @if (SHOW_AUTO_REFRESH) {\n <fieldset class=\"c8y-fieldset\">\n <legend class=\"d-flex\">\n <div class=\"standalone btn-icon-dot__item auto-refresh m-r-4\">\n <i [c8yIcon]=\"'refresh'\"></i>\n </div>\n {{ 'Auto refresh' | translate }}\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"REFRESH_POPOVER_MESSAGE | translate\"\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-8 form-group-sm p-t-16 p-b-16\">\n <div class=\"d-flex gap-8 a-i-center\">\n <label class=\"c8y-switch c8y-switch--inline\">\n <input\n type=\"checkbox\"\n #arInput\n formControlName=\"isAutoRefreshEnabled\"\n />\n <span></span>\n <span>\n {{ 'Auto refresh enabled' | translate }}\n </span>\n </label>\n </div>\n </c8y-form-group>\n </fieldset>\n }\n </div>\n </div>\n </form>\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i3.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3622
3842
|
}
|
|
3623
3843
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: LiveModeConfigurationControlsComponent, decorators: [{
|
|
3624
3844
|
type: Component,
|
|
@@ -4057,7 +4277,7 @@ class ConfigurationCollapseComponent {
|
|
|
4057
4277
|
this.hasPendingChanges.set(!isEqual(snapshot, latest));
|
|
4058
4278
|
}
|
|
4059
4279
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ConfigurationCollapseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4060
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ConfigurationCollapseComponent, isStandalone: true, selector: "c8y-configuration-collapse", inputs: { supportedModes: { classPropertyName: "supportedModes", publicName: "supportedModes", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", refreshOptionChange: "refreshOptionChange", savePreferenceChange: "savePreferenceChange" }, host: { classAttribute: "d-contents" }, ngImport: i0, template: "<div\n class=\"c8y-global-context\"\n data-cy=\"global-context--configuration-panel\"\n [collapse]=\"isCollapsed()\"\n (collapsed)=\"onCollapsed()\"\n (expanded)=\"onExpanded()\"\n [isAnimated]=\"true\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span\n class=\"h4\"\n translate\n >\n Time mode\n </span>\n </div>\n <div>\n @if (!isCollapsed()) {\n <c8y-configuration-controls\n [activeMode]=\"activeMode()\"\n [liveContext]=\"liveViewContext()\"\n [historyContext]=\"historyViewContext()\"\n [supportedModes]=\"supportedModes()\"\n (refreshOptionChange)=\"onModeSelected($event)\"\n (contextChange)=\"onModeChange($event)\"\n (validationStatus)=\"onValidationStatusChange($event)\"\n ></c8y-configuration-controls>\n }\n </div>\n <div class=\"c8y-top-drawer--footer\">\n <div class=\"d-flex a-i-center gap-8\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Close help' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"toggle()\"\n data-cy=\"global-context--Close-button\"\n translate\n >\n Close\n </button>\n <button\n class=\"btn btn-primary\"\n [title]=\"'Apply global context' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"!hasPendingChanges() || !isFormValid()\"\n translate\n data-cy=\"global-date-context--Apply-button\"\n >\n Apply\n </button>\n\n <label class=\"c8y-checkbox d-flex align-items-center m-b-0\">\n <input\n class=\"m-r-4\"\n type=\"checkbox\"\n [ngModel]=\"shouldSave()\"\n (ngModelChange)=\"shouldSaveInDashboard($event)\"\n />\n <span class=\"a-s-center m-r-8\"></span>\n <span\n class=\"text-truncate\"\n translate\n >\n Save in dashboard configuration\n </span>\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"helpText | translate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: CollapseModule }, { kind: "directive", type: i1$2.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type:
|
|
4280
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ConfigurationCollapseComponent, isStandalone: true, selector: "c8y-configuration-collapse", inputs: { supportedModes: { classPropertyName: "supportedModes", publicName: "supportedModes", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", refreshOptionChange: "refreshOptionChange", savePreferenceChange: "savePreferenceChange" }, host: { classAttribute: "d-contents" }, ngImport: i0, template: "<div\n class=\"c8y-global-context\"\n data-cy=\"global-context--configuration-panel\"\n [collapse]=\"isCollapsed()\"\n (collapsed)=\"onCollapsed()\"\n (expanded)=\"onExpanded()\"\n [isAnimated]=\"true\"\n>\n <div class=\"p-t-16 p-b-16 p-l-24 p-r-24 separator-bottom\">\n <span\n class=\"h4\"\n translate\n >\n Time mode\n </span>\n </div>\n <div>\n @if (!isCollapsed()) {\n <c8y-configuration-controls\n [activeMode]=\"activeMode()\"\n [liveContext]=\"liveViewContext()\"\n [historyContext]=\"historyViewContext()\"\n [supportedModes]=\"supportedModes()\"\n (refreshOptionChange)=\"onModeSelected($event)\"\n (contextChange)=\"onModeChange($event)\"\n (validationStatus)=\"onValidationStatusChange($event)\"\n ></c8y-configuration-controls>\n }\n </div>\n <div class=\"c8y-top-drawer--footer\">\n <div class=\"d-flex a-i-center gap-8\">\n <button\n class=\"btn btn-default\"\n [title]=\"'Close help' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"toggle()\"\n data-cy=\"global-context--Close-button\"\n translate\n >\n Close\n </button>\n <button\n class=\"btn btn-primary\"\n [title]=\"'Apply global context' | translate\"\n aria-controls=\"collapseHelp\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n type=\"button\"\n (click)=\"apply()\"\n [disabled]=\"!hasPendingChanges() || !isFormValid()\"\n translate\n data-cy=\"global-date-context--Apply-button\"\n >\n Apply\n </button>\n\n <label class=\"c8y-checkbox d-flex align-items-center m-b-0\">\n <input\n class=\"m-r-4\"\n type=\"checkbox\"\n [ngModel]=\"shouldSave()\"\n (ngModelChange)=\"shouldSaveInDashboard($event)\"\n />\n <span class=\"a-s-center m-r-8\"></span>\n <span\n class=\"text-truncate\"\n translate\n >\n Save in dashboard configuration\n </span>\n <button\n class=\"btn-help btn-help--sm m-l-4\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"helpText | translate\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n [adaptivePosition]=\"true\"\n ></button>\n </label>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: CollapseModule }, { kind: "directive", type: i1$2.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i3.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "intervalOptions", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4061
4281
|
}
|
|
4062
4282
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ConfigurationCollapseComponent, decorators: [{
|
|
4063
4283
|
type: Component,
|
|
@@ -4612,16 +4832,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
4612
4832
|
class AggregationDisplayComponent {
|
|
4613
4833
|
constructor() {
|
|
4614
4834
|
this.aggregation = input(null, ...(ngDevMode ? [{ debugName: "aggregation" }] : /* istanbul ignore next */ []));
|
|
4615
|
-
|
|
4835
|
+
/**
|
|
4836
|
+
* When true, the display shows "Auto" regardless of `aggregation`. Auto mode stores a null
|
|
4837
|
+
* aggregation, so without this flag the display would fall back to "No aggregation".
|
|
4838
|
+
*/
|
|
4839
|
+
this.autoMode = input(false, ...(ngDevMode ? [{ debugName: "autoMode" }] : /* istanbul ignore next */ []));
|
|
4840
|
+
/** Number of aggregation points, shown as a badge next to "Auto" while auto mode is active. */
|
|
4841
|
+
this.autoPoints = input(null, ...(ngDevMode ? [{ debugName: "autoPoints" }] : /* istanbul ignore next */ []));
|
|
4842
|
+
/** Whether the point count is kept on zoom; surfaced in the tooltip while auto mode is active. */
|
|
4843
|
+
this.autoKeepPointCount = input(null, ...(ngDevMode ? [{ debugName: "autoKeepPointCount" }] : /* istanbul ignore next */ []));
|
|
4844
|
+
// Exposed for the template's tooltip (`@let`).
|
|
4616
4845
|
this.AGGREGATION_TEXTS = AGGREGATION_TEXTS;
|
|
4846
|
+
this.AUTO_AGGREGATION_TEXT = AUTO_AGGREGATION_TEXT;
|
|
4847
|
+
this.AUTO_POINTS_TOOLTIP = AUTO_POINTS_TOOLTIP;
|
|
4848
|
+
this.AUTO_POINTS_TOOLTIP_KEPT = AUTO_POINTS_TOOLTIP_KEPT;
|
|
4849
|
+
/** Short label shown as the current aggregation, accounting for auto mode. */
|
|
4850
|
+
this.displayText = computed(() => {
|
|
4851
|
+
if (this.autoMode()) {
|
|
4852
|
+
return AUTO_AGGREGATION_TEXT;
|
|
4853
|
+
}
|
|
4854
|
+
const aggregation = this.aggregation();
|
|
4855
|
+
return aggregation ? AGGREGATION_LABELS[aggregation] : AGGREGATION_LABELS.NONE;
|
|
4856
|
+
}, ...(ngDevMode ? [{ debugName: "displayText" }] : /* istanbul ignore next */ []));
|
|
4857
|
+
/** Icon shown next to the current aggregation, accounting for auto mode. */
|
|
4858
|
+
this.displayIcon = computed(() => {
|
|
4859
|
+
if (this.autoMode()) {
|
|
4860
|
+
return AGGREGATION_ICON_TYPE.AUTO;
|
|
4861
|
+
}
|
|
4862
|
+
const aggregation = this.aggregation();
|
|
4863
|
+
return aggregation ? AGGREGATION_ICONS[aggregation] : AGGREGATION_ICONS.undefined;
|
|
4864
|
+
}, ...(ngDevMode ? [{ debugName: "displayIcon" }] : /* istanbul ignore next */ []));
|
|
4617
4865
|
}
|
|
4618
4866
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AggregationDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4619
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
4867
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: AggregationDisplayComponent, isStandalone: true, selector: "c8y-aggregation-display", inputs: { aggregation: { classPropertyName: "aggregation", publicName: "aggregation", isSignal: true, isRequired: false, transformFunction: null }, autoMode: { classPropertyName: "autoMode", publicName: "autoMode", isSignal: true, isRequired: false, transformFunction: null }, autoPoints: { classPropertyName: "autoPoints", publicName: "autoPoints", isSignal: true, isRequired: false, transformFunction: null }, autoKeepPointCount: { classPropertyName: "autoKeepPointCount", publicName: "autoKeepPointCount", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"d-flex a-i-center l-h-tight form-control\">\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"displayIcon()\"\n ></i>\n <div class=\"d-col text-left fit-w min-width-0\">\n <span\n class=\"text-10 l-h-1 text-muted text-truncate\"\n title=\"{{ 'Aggregation' | translate }}\"\n >\n {{ 'Aggregation' | translate }}\n </span>\n @let titleText =\n autoMode()\n ? autoPoints() != null\n ? ((autoKeepPointCount() ? AUTO_POINTS_TOOLTIP_KEPT : AUTO_POINTS_TOOLTIP)\n | translate: { points: autoPoints() })\n : (AUTO_AGGREGATION_TEXT | translate)\n : aggregation()\n ? (AGGREGATION_TEXTS[aggregation()] | translate)\n : (AGGREGATION_TEXTS.null | translate);\n <span\n class=\"text-12 l-h-1 text-medium d-flex a-i-center gap-4\"\n [title]=\"titleText\"\n data-cy=\"global-date-context--Aggregation-display-value\"\n >\n <span class=\"text-truncate\">{{ displayText() | translate }}</span>\n @if (autoMode() && autoPoints() != null) {\n <span\n class=\"m-l-auto badge badge-info flex-no-shrink l-h-1 text-10\"\n style=\"min-height: 12px\"\n >\n {{ autoPoints() }}\n </span>\n }\n </span>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4620
4868
|
}
|
|
4621
4869
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: AggregationDisplayComponent, decorators: [{
|
|
4622
4870
|
type: Component,
|
|
4623
|
-
args: [{ selector: 'c8y-aggregation-display', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [C8yTranslatePipe, IconDirective], template: "<div class=\"d-flex a-i-center l-h-tight form-control\">\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"
|
|
4624
|
-
}], propDecorators: { aggregation: [{ type: i0.Input, args: [{ isSignal: true, alias: "aggregation", required: false }] }] } });
|
|
4871
|
+
args: [{ selector: 'c8y-aggregation-display', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [C8yTranslatePipe, IconDirective], template: "<div class=\"d-flex a-i-center l-h-tight form-control\">\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"displayIcon()\"\n ></i>\n <div class=\"d-col text-left fit-w min-width-0\">\n <span\n class=\"text-10 l-h-1 text-muted text-truncate\"\n title=\"{{ 'Aggregation' | translate }}\"\n >\n {{ 'Aggregation' | translate }}\n </span>\n @let titleText =\n autoMode()\n ? autoPoints() != null\n ? ((autoKeepPointCount() ? AUTO_POINTS_TOOLTIP_KEPT : AUTO_POINTS_TOOLTIP)\n | translate: { points: autoPoints() })\n : (AUTO_AGGREGATION_TEXT | translate)\n : aggregation()\n ? (AGGREGATION_TEXTS[aggregation()] | translate)\n : (AGGREGATION_TEXTS.null | translate);\n <span\n class=\"text-12 l-h-1 text-medium d-flex a-i-center gap-4\"\n [title]=\"titleText\"\n data-cy=\"global-date-context--Aggregation-display-value\"\n >\n <span class=\"text-truncate\">{{ displayText() | translate }}</span>\n @if (autoMode() && autoPoints() != null) {\n <span\n class=\"m-l-auto badge badge-info flex-no-shrink l-h-1 text-10\"\n style=\"min-height: 12px\"\n >\n {{ autoPoints() }}\n </span>\n }\n </span>\n </div>\n</div>\n" }]
|
|
4872
|
+
}], propDecorators: { aggregation: [{ type: i0.Input, args: [{ isSignal: true, alias: "aggregation", required: false }] }], autoMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoMode", required: false }] }], autoPoints: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoPoints", required: false }] }], autoKeepPointCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoKeepPointCount", required: false }] }] } });
|
|
4625
4873
|
|
|
4626
4874
|
/**
|
|
4627
4875
|
* Source of auto-refresh state change.
|
|
@@ -4954,7 +5202,7 @@ let ContextControlsComponent$1 = class ContextControlsComponent {
|
|
|
4954
5202
|
return pick(settings, requiredKeys);
|
|
4955
5203
|
}
|
|
4956
5204
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ContextControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4957
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ContextControlsComponent, isStandalone: true, selector: "c8y-context-controls", inputs: { showDisplayModeLabel: "showDisplayModeLabel", isLoading: "isLoading", settings: "settings", context: "context" }, outputs: { contextChange: "contextChange", refresh: "refresh", contextClick: "contextClick" }, ngImport: i0, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n @let refreshIntervalValue = form?.get('refreshInterval')?.value;\n @let isLiveMode = refreshOption === REFRESH_OPTION.LIVE;\n\n @if (isLiveMode) {\n <form\n class=\"input-group\"\n [formGroup]=\"form\"\n >\n <c8y-auto-refresh-control\n #autoRefreshControl\n [isLoading]=\"isLoading\"\n [isAutoRefreshConnected]=\"isAutoRefreshConnected\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"refreshIntervalValue\"\n (refresh)=\"refresh.emit()\"\n ></c8y-auto-refresh-control>\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8 min-width-0\"\n style=\"margin-left: -1px\"\n (click)=\"contextClick.emit($event)\"\n >\n <div\n class=\"d-col a-i-start form-control\"\n style=\"flex: 0\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n @let interval = form.get('dateTimeContext')?.value?.interval;\n @let isCustomInterval = interval === 'custom';\n\n <c8y-time-range-display\n style=\"margin-left: -1px; min-width: 0\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n } @else {\n <form [formGroup]=\"form\">\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n (click)=\"contextClick.emit($event)\"\n >\n <div\n class=\"d-col a-i-center form-control\"\n style=\"flex: 0\"\n >\n <i class=\"dlt-c8y-icon-schedule1 icon-20 text-primary\"></i>\n </div>\n\n <div\n class=\"d-col a-i-start form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n <c8y-time-range-display\n style=\"margin-left: -1px; min-width: 0\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n <c8y-aggregation-display\n style=\"margin-left: -1px; min-width: 0\"\n [aggregation]=\"form.get('aggregation')?.value\"\n ></c8y-aggregation-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "ngmodule", type: CollapseModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: TimeRangeDisplayComponent, selector: "c8y-time-range-display", inputs: ["dateTimeContext", "mode"] }, { kind: "component", type: AggregationDisplayComponent, selector: "c8y-aggregation-display", inputs: ["aggregation"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5205
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ContextControlsComponent, isStandalone: true, selector: "c8y-context-controls", inputs: { showDisplayModeLabel: "showDisplayModeLabel", isLoading: "isLoading", settings: "settings", context: "context" }, outputs: { contextChange: "contextChange", refresh: "refresh", contextClick: "contextClick" }, ngImport: i0, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n @let refreshIntervalValue = form?.get('refreshInterval')?.value;\n @let isLiveMode = refreshOption === REFRESH_OPTION.LIVE;\n\n @if (isLiveMode) {\n <form\n class=\"input-group\"\n [formGroup]=\"form\"\n >\n <c8y-auto-refresh-control\n #autoRefreshControl\n [isLoading]=\"isLoading\"\n [isAutoRefreshConnected]=\"isAutoRefreshConnected\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"refreshIntervalValue\"\n (refresh)=\"refresh.emit()\"\n ></c8y-auto-refresh-control>\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8 min-width-0\"\n style=\"margin-left: -1px\"\n (click)=\"contextClick.emit($event)\"\n >\n <div\n class=\"d-col a-i-start form-control\"\n style=\"flex: 0\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n @let interval = form.get('dateTimeContext')?.value?.interval;\n @let isCustomInterval = interval === 'custom';\n\n <c8y-time-range-display\n style=\"margin-left: -1px; min-width: 0\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n } @else {\n <form [formGroup]=\"form\">\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n (click)=\"contextClick.emit($event)\"\n >\n <div\n class=\"d-col a-i-center form-control\"\n style=\"flex: 0\"\n >\n <i class=\"dlt-c8y-icon-schedule1 icon-20 text-primary\"></i>\n </div>\n\n <div\n class=\"d-col a-i-start form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n <c8y-time-range-display\n style=\"margin-left: -1px; min-width: 0\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n <c8y-aggregation-display\n style=\"margin-left: -1px; min-width: 0\"\n [aggregation]=\"form.get('aggregation')?.value\"\n [autoMode]=\"!!context?.autoAggregation\"\n [autoPoints]=\"context?.autoAggregation?.datapoints\"\n [autoKeepPointCount]=\"context?.autoAggregation?.keepDataOnZoomIn\"\n ></c8y-aggregation-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "ngmodule", type: CollapseModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: TimeRangeDisplayComponent, selector: "c8y-time-range-display", inputs: ["dateTimeContext", "mode"] }, { kind: "component", type: AggregationDisplayComponent, selector: "c8y-aggregation-display", inputs: ["aggregation", "autoMode", "autoPoints", "autoKeepPointCount"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4958
5206
|
};
|
|
4959
5207
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ContextControlsComponent$1, decorators: [{
|
|
4960
5208
|
type: Component,
|
|
@@ -4970,7 +5218,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
4970
5218
|
TimeRangeDisplayComponent,
|
|
4971
5219
|
AggregationDisplayComponent,
|
|
4972
5220
|
AsyncPipe
|
|
4973
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n @let refreshIntervalValue = form?.get('refreshInterval')?.value;\n @let isLiveMode = refreshOption === REFRESH_OPTION.LIVE;\n\n @if (isLiveMode) {\n <form\n class=\"input-group\"\n [formGroup]=\"form\"\n >\n <c8y-auto-refresh-control\n #autoRefreshControl\n [isLoading]=\"isLoading\"\n [isAutoRefreshConnected]=\"isAutoRefreshConnected\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"refreshIntervalValue\"\n (refresh)=\"refresh.emit()\"\n ></c8y-auto-refresh-control>\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8 min-width-0\"\n style=\"margin-left: -1px\"\n (click)=\"contextClick.emit($event)\"\n >\n <div\n class=\"d-col a-i-start form-control\"\n style=\"flex: 0\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n @let interval = form.get('dateTimeContext')?.value?.interval;\n @let isCustomInterval = interval === 'custom';\n\n <c8y-time-range-display\n style=\"margin-left: -1px; min-width: 0\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n } @else {\n <form [formGroup]=\"form\">\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n (click)=\"contextClick.emit($event)\"\n >\n <div\n class=\"d-col a-i-center form-control\"\n style=\"flex: 0\"\n >\n <i class=\"dlt-c8y-icon-schedule1 icon-20 text-primary\"></i>\n </div>\n\n <div\n class=\"d-col a-i-start form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n <c8y-time-range-display\n style=\"margin-left: -1px; min-width: 0\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n <c8y-aggregation-display\n style=\"margin-left: -1px; min-width: 0\"\n [aggregation]=\"form.get('aggregation')?.value\"\n ></c8y-aggregation-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n }\n}\n" }]
|
|
5221
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (form) {\n @let SHOW_TIME_CONTEXT = settings.showTimeContext;\n @let SHOW_AGGREGATION = settings.showAggregation;\n @let SHOW_AUTO_REFRESH = settings.showAutoRefresh;\n @let refreshIntervalValue = form?.get('refreshInterval')?.value;\n @let isLiveMode = refreshOption === REFRESH_OPTION.LIVE;\n\n @if (isLiveMode) {\n <form\n class=\"input-group\"\n [formGroup]=\"form\"\n >\n <c8y-auto-refresh-control\n #autoRefreshControl\n [isLoading]=\"isLoading\"\n [isAutoRefreshConnected]=\"isAutoRefreshConnected\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"refreshIntervalValue\"\n (refresh)=\"refresh.emit()\"\n ></c8y-auto-refresh-control>\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8 min-width-0\"\n style=\"margin-left: -1px\"\n (click)=\"contextClick.emit($event)\"\n >\n <div\n class=\"d-col a-i-start form-control\"\n style=\"flex: 0\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n @let interval = form.get('dateTimeContext')?.value?.interval;\n @let isCustomInterval = interval === 'custom';\n\n <c8y-time-range-display\n style=\"margin-left: -1px; min-width: 0\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n } @else {\n <form [formGroup]=\"form\">\n <button\n class=\"btn-clean d-flex p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n (click)=\"contextClick.emit($event)\"\n >\n <div\n class=\"d-col a-i-center form-control\"\n style=\"flex: 0\"\n >\n <i class=\"dlt-c8y-icon-schedule1 icon-20 text-primary\"></i>\n </div>\n\n <div\n class=\"d-col a-i-start form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <p class=\"text-muted fit-w text-10 l-h-1\">\n {{ 'Time mode' | translate }}\n </p>\n <p\n class=\"text-bold text-12 fit-w l-h-1\"\n data-cy=\"global-time-context-controls--Display-mode\"\n >\n {{ refreshOption | translate | titlecase }}\n </p>\n </div>\n\n <c8y-time-range-display\n style=\"margin-left: -1px; min-width: 0\"\n [dateTimeContext]=\"form.get('dateTimeContext')?.value\"\n ></c8y-time-range-display>\n <c8y-aggregation-display\n style=\"margin-left: -1px; min-width: 0\"\n [aggregation]=\"form.get('aggregation')?.value\"\n [autoMode]=\"!!context?.autoAggregation\"\n [autoPoints]=\"context?.autoAggregation?.datapoints\"\n [autoKeepPointCount]=\"context?.autoAggregation?.keepDataOnZoomIn\"\n ></c8y-aggregation-display>\n\n @if (!(isAnySettingsEnabled$ | async)) {\n <div\n class=\"d-col a-i-center form-control\"\n style=\"margin-left: -1px; flex: 0\"\n >\n <i\n class=\"dlt-c8y-icon-disconnected icon-20 text-danger\"\n [tooltip]=\"'No synced widgets' | translate\"\n placement=\"right\"\n container=\"body\"\n [delay]=\"500\"\n data-cy=\"global-time-context-controls--Widgets-disconnected\"\n ></i>\n </div>\n }\n </button>\n </form>\n }\n}\n" }]
|
|
4974
5222
|
}], propDecorators: { showDisplayModeLabel: [{
|
|
4975
5223
|
type: Input
|
|
4976
5224
|
}], isLoading: [{
|
|
@@ -5223,6 +5471,7 @@ class GlobalContextComponent {
|
|
|
5223
5471
|
return pick(changes, [
|
|
5224
5472
|
'dateTimeContext',
|
|
5225
5473
|
'aggregation',
|
|
5474
|
+
'autoAggregation',
|
|
5226
5475
|
'isAutoRefreshEnabled',
|
|
5227
5476
|
'refreshInterval',
|
|
5228
5477
|
'refreshOption',
|
|
@@ -6453,6 +6702,10 @@ function resolveConfigurationValue(key, sources, localStateValues, globalStateVa
|
|
|
6453
6702
|
return undefined;
|
|
6454
6703
|
case 'isGlobalContextReady':
|
|
6455
6704
|
return undefined;
|
|
6705
|
+
case 'autoAggregation':
|
|
6706
|
+
return undefined;
|
|
6707
|
+
case 'aggregationFunction':
|
|
6708
|
+
return undefined;
|
|
6456
6709
|
default: {
|
|
6457
6710
|
// Exhaustive check: ensures all keys are handled at compile time
|
|
6458
6711
|
const _exhaustive = key;
|
|
@@ -8641,7 +8894,7 @@ class GlobalContextInlineComponent {
|
|
|
8641
8894
|
};
|
|
8642
8895
|
}
|
|
8643
8896
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: GlobalContextInlineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8644
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: GlobalContextInlineComponent, isStandalone: true, selector: "c8y-global-context-inline", inputs: { widgetControls: { classPropertyName: "widgetControls", publicName: "widgetControls", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, dashboardChildForLegacy: { classPropertyName: "dashboardChildForLegacy", publicName: "dashboardChildForLegacy", isSignal: true, isRequired: false, transformFunction: null }, disableRefreshEmits: { classPropertyName: "disableRefreshEmits", publicName: "disableRefreshEmits", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refresh: "refresh", globalContextChange: "globalContextChange" }, providers: [GlobalContextInlineOrchestratorService], viewQueries: [{ propertyName: "headerTemplateRef", first: true, predicate: ["headerContent"], descendants: true, read: TemplateRef, static: true }], exportAs: ["globalContextInline"], ngImport: i0, template: "<ng-template #headerContent>\n @let linkModel = linkDisplayModel();\n <ng-content select=\"#header\"></ng-content>\n\n @if (shouldShowHeaderLinks()) {\n <c8y-global-context-link-controls\n [linkStates]=\"linkModel.linkStates\"\n [controlConfigs]=\"linkModel.controlConfig\"\n (allLinksToggled)=\"toggleAllLinks($event)\"\n ></c8y-global-context-link-controls>\n }\n</ng-template>\n\n<ng-template #inlineContent>\n @let settings = inlineSettings();\n @let linkModel = linkDisplayModel();\n\n @if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 inner-scroll\"\n [ngClass]=\"{\n 'p-b-8':\n settings.showTimeContext ||\n settings.showRefresh ||\n settings.showAutoRefresh ||\n settings.showAggregation\n }\"\n [formGroup]=\"form\"\n >\n <div class=\"input-group w-auto input-group-sm\">\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n data-cy=\"global-inline-date-context--Aggregation-display\"\n [disabledAggregations]=\"getDisabledAggregations()\"\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n @if (settings.showAutoRefresh) {\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading()\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"getAutoRefreshSeconds()\"\n [isAutoRefreshConnected]=\"linkModel.linkStates.isAutoRefreshEnabled ?? false\"\n (refresh)=\"onLocalRefreshTrigger()\"\n ></c8y-auto-refresh-control>\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"getIntervalDisableConfig()\"\n [config]=\"\n isHistoryMode\n ? { showDateTo: true, showDateFrom: true }\n : { showDateTo: false, showDateFrom: true }\n \"\n ></c8y-date-time-context-picker>\n }\n\n @if (settings.showRefresh) {\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 container=\"body\"\n type=\"button\"\n data-cy=\"global-inline-date-context--reload-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading()\"\n (click)=\"refresh.emit(null)\"\n >\n <i\n [class.icon-spin]=\"isLoading()\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n }\n\n <ng-content select=\"#body\"></ng-content>\n</ng-template>\n\n@switch (effectiveConfig().displayMode) {\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG) {\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @default {\n @if (shouldRenderHeaderInline()) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n }\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: GlobalContextLinkControlsComponent, selector: "c8y-global-context-link-controls", inputs: ["linkStates", "controlConfigs"], outputs: ["allLinksToggled"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8897
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: GlobalContextInlineComponent, isStandalone: true, selector: "c8y-global-context-inline", inputs: { widgetControls: { classPropertyName: "widgetControls", publicName: "widgetControls", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, dashboardChildForLegacy: { classPropertyName: "dashboardChildForLegacy", publicName: "dashboardChildForLegacy", isSignal: true, isRequired: false, transformFunction: null }, disableRefreshEmits: { classPropertyName: "disableRefreshEmits", publicName: "disableRefreshEmits", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { refresh: "refresh", globalContextChange: "globalContextChange" }, providers: [GlobalContextInlineOrchestratorService], viewQueries: [{ propertyName: "headerTemplateRef", first: true, predicate: ["headerContent"], descendants: true, read: TemplateRef, static: true }], exportAs: ["globalContextInline"], ngImport: i0, template: "<ng-template #headerContent>\n @let linkModel = linkDisplayModel();\n <ng-content select=\"#header\"></ng-content>\n\n @if (shouldShowHeaderLinks()) {\n <c8y-global-context-link-controls\n [linkStates]=\"linkModel.linkStates\"\n [controlConfigs]=\"linkModel.controlConfig\"\n (allLinksToggled)=\"toggleAllLinks($event)\"\n ></c8y-global-context-link-controls>\n }\n</ng-template>\n\n<ng-template #inlineContent>\n @let settings = inlineSettings();\n @let linkModel = linkDisplayModel();\n\n @if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 inner-scroll\"\n [ngClass]=\"{\n 'p-b-8':\n settings.showTimeContext ||\n settings.showRefresh ||\n settings.showAutoRefresh ||\n settings.showAggregation\n }\"\n [formGroup]=\"form\"\n >\n <div class=\"input-group w-auto input-group-sm\">\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n data-cy=\"global-inline-date-context--Aggregation-display\"\n [disabledAggregations]=\"getDisabledAggregations()\"\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n @if (settings.showAutoRefresh) {\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading()\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"getAutoRefreshSeconds()\"\n [isAutoRefreshConnected]=\"linkModel.linkStates.isAutoRefreshEnabled ?? false\"\n (refresh)=\"onLocalRefreshTrigger()\"\n ></c8y-auto-refresh-control>\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"getIntervalDisableConfig()\"\n [config]=\"\n isHistoryMode\n ? { showDateTo: true, showDateFrom: true }\n : { showDateTo: false, showDateFrom: true }\n \"\n ></c8y-date-time-context-picker>\n }\n\n @if (settings.showRefresh) {\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 container=\"body\"\n type=\"button\"\n data-cy=\"global-inline-date-context--reload-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n [disabled]=\"isLoading()\"\n (click)=\"refresh.emit(null)\"\n >\n <i\n [class.icon-spin]=\"isLoading()\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n }\n\n <ng-content select=\"#body\"></ng-content>\n</ng-template>\n\n@switch (effectiveConfig().displayMode) {\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG) {\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @case (GLOBAL_CONTEXT_DISPLAY_MODE.VIEW_AND_CONFIG) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n @default {\n @if (shouldRenderHeaderInline()) {\n <ng-container [ngTemplateOutlet]=\"headerContent\"></ng-container>\n }\n <ng-container [ngTemplateOutlet]=\"inlineContent\"></ng-container>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: GlobalContextLinkControlsComponent, selector: "c8y-global-context-link-controls", inputs: ["linkStates", "controlConfigs"], outputs: ["allLinksToggled"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout", "showAutoMode", "autoModeActive", "autoModeDisabled"], outputs: ["autoModeChange"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8645
8898
|
}
|
|
8646
8899
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: GlobalContextInlineComponent, decorators: [{
|
|
8647
8900
|
type: Component,
|
|
@@ -9523,7 +9776,7 @@ class GlobalContextWidgetConfigComponent {
|
|
|
9523
9776
|
></c8y-global-context-config>
|
|
9524
9777
|
</fieldset>
|
|
9525
9778
|
}
|
|
9526
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ConfigContextSelectorComponent, selector: "c8y-config-context-selector" }, { kind: "component", type: GlobalContextConfigComponent, selector: "c8y-global-context-config", inputs: ["config", "isLoading", "widgetControls", "liveSnapshot", "historySnapshot"], outputs: ["refresh", "globalContextChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type:
|
|
9779
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ConfigContextSelectorComponent, selector: "c8y-config-context-selector" }, { kind: "component", type: GlobalContextConfigComponent, selector: "c8y-global-context-config", inputs: ["config", "isLoading", "widgetControls", "liveSnapshot", "historySnapshot"], outputs: ["refresh", "globalContextChange"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i3.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9527
9780
|
}
|
|
9528
9781
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: GlobalContextWidgetConfigComponent, decorators: [{
|
|
9529
9782
|
type: Component,
|
|
@@ -9746,7 +9999,7 @@ class PreviewControlsComponent {
|
|
|
9746
9999
|
this.config.displayMode = GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD;
|
|
9747
10000
|
}
|
|
9748
10001
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: PreviewControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9749
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: PreviewControlsComponent, isStandalone: true, selector: "c8y-preview-controls", inputs: { widgetControls: "widgetControls", config: "config" }, ngImport: i0, template: "<!-- Main Controls -->\n@let isConfigMode = config?.displayMode === GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;\n@let settings = inlineControlsSettings$ | async;\n\n@if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <!-- Control Group Container -->\n <div class=\"input-group w-auto\">\n <!-- Aggregation Picker -->\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n <!-- Auto Refresh Controls -->\n @if (settings.showAutoRefresh) {\n <!-- Auto Refresh Toggle -->\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"form.get('refreshInterval')?.value\"\n ></c8y-auto-refresh-control>\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n @let configValue =\n isHistoryMode\n ? {\n showDateTo: true,\n showDateFrom: true\n }\n : {\n showDateTo: false,\n showDateFrom: true\n };\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"shouldDisableCustomInterval\"\n [config]=\"configValue\"\n ></c8y-date-time-context-picker>\n }\n\n <!-- Manual Refresh Button -->\n @if (settings.showRefresh) {\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 [delay]=\"500\"\n [disabled]=\"isLoading\"\n >\n <i\n [class.icon-spin]=\"isLoading\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n}\n", styles: [":host{position:relative;display:block;cursor:not-allowed}:host form{position:relative;pointer-events:none;-webkit-user-select:none;user-select:none}:host form:after{content:\"\";position:absolute;inset:0;background:#ffffff0d;z-index:1;pointer-events:none}:host form button,:host form input,:host form select,:host form .dropdown-toggle,:host form .btn{cursor:not-allowed!important;opacity:.85}:host form *{pointer-events:none!important;-webkit-user-select:none!important;user-select:none!important}\n"], dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
10002
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: PreviewControlsComponent, isStandalone: true, selector: "c8y-preview-controls", inputs: { widgetControls: "widgetControls", config: "config" }, ngImport: i0, template: "<!-- Main Controls -->\n@let isConfigMode = config?.displayMode === GLOBAL_CONTEXT_DISPLAY_MODE.CONFIG;\n@let settings = inlineControlsSettings$ | async;\n\n@if (form && settings) {\n <form\n class=\"d-flex gap-16 p-l-16 p-r-16 p-b-8 inner-scroll\"\n [formGroup]=\"form\"\n >\n <!-- Control Group Container -->\n <div class=\"input-group w-auto\">\n <!-- Aggregation Picker -->\n @if (settings.showAggregation) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [resetToDefault]=\"true\"\n ></c8y-aggregation-picker>\n }\n\n <!-- Auto Refresh Controls -->\n @if (settings.showAutoRefresh) {\n <!-- Auto Refresh Toggle -->\n <c8y-auto-refresh-control\n [isLoading]=\"isLoading\"\n [disableCounter]=\"shouldDisableCounter\"\n formControlName=\"isAutoRefreshEnabled\"\n [autoRefreshSeconds]=\"form.get('refreshInterval')?.value\"\n ></c8y-auto-refresh-control>\n }\n\n @if (settings.showTimeContext) {\n @let isHistoryMode = form.get('refreshOption')?.value === REFRESH_OPTION.HISTORY;\n @let configValue =\n isHistoryMode\n ? {\n showDateTo: true,\n showDateFrom: true\n }\n : {\n showDateTo: false,\n showDateFrom: true\n };\n <c8y-date-time-context-picker\n style=\"margin-left: -1px\"\n formControlName=\"dateTimeContext\"\n [shouldDisableInterval]=\"shouldDisableCustomInterval\"\n [config]=\"configValue\"\n ></c8y-date-time-context-picker>\n }\n\n <!-- Manual Refresh Button -->\n @if (settings.showRefresh) {\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 [delay]=\"500\"\n [disabled]=\"isLoading\"\n >\n <i\n [class.icon-spin]=\"isLoading\"\n [c8yIcon]=\"'refresh'\"\n ></i>\n </button>\n </div>\n }\n </div>\n </form>\n}\n", styles: [":host{position:relative;display:block;cursor:not-allowed}:host form{position:relative;pointer-events:none;-webkit-user-select:none;user-select:none}:host form:after{content:\"\";position:absolute;inset:0;background:#ffffff0d;z-index:1;pointer-events:none}:host form button,:host form input,:host form select,:host form .dropdown-toggle,:host form .btn{cursor:not-allowed!important;opacity:.85}:host form *{pointer-events:none!important;-webkit-user-select:none!important;user-select:none!important}\n"], dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout", "showAutoMode", "autoModeActive", "autoModeDisabled"], outputs: ["autoModeChange"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9750
10003
|
}
|
|
9751
10004
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: PreviewControlsComponent, decorators: [{
|
|
9752
10005
|
type: Component,
|
|
@@ -10866,7 +11119,13 @@ const CONTEXT_FEATURE = {
|
|
|
10866
11119
|
/** Manual refresh button - live mode only */
|
|
10867
11120
|
REFRESH_LIVE: 'refreshLive',
|
|
10868
11121
|
/** Manual refresh button - history mode only */
|
|
10869
|
-
REFRESH_HISTORY: 'refreshHistory'
|
|
11122
|
+
REFRESH_HISTORY: 'refreshHistory',
|
|
11123
|
+
/**
|
|
11124
|
+
* Automatic aggregation mode ("Auto"). Computes the interval from the time frame and a target
|
|
11125
|
+
* datapoint count. Only meaningful for the Data graph widget; presets without it keep the
|
|
11126
|
+
* "Auto" option visible but disabled.
|
|
11127
|
+
*/
|
|
11128
|
+
AUTO_AGGREGATION: 'autoAggregation'
|
|
10870
11129
|
};
|
|
10871
11130
|
/** Preset name constants for type-safe access */
|
|
10872
11131
|
const PRESET_NAME = {
|
|
@@ -11041,6 +11300,7 @@ const CONTROL_PRESETS = {
|
|
|
11041
11300
|
CONTEXT_FEATURE.HISTORY_TIME,
|
|
11042
11301
|
CONTEXT_FEATURE.AUTO_REFRESH,
|
|
11043
11302
|
CONTEXT_FEATURE.AGGREGATION,
|
|
11303
|
+
CONTEXT_FEATURE.AUTO_AGGREGATION,
|
|
11044
11304
|
CONTEXT_FEATURE.REFRESH
|
|
11045
11305
|
],
|
|
11046
11306
|
config: [CONTEXT_FEATURE.AUTO_REFRESH, CONTEXT_FEATURE.REFRESH],
|
|
@@ -11048,6 +11308,7 @@ const CONTROL_PRESETS = {
|
|
|
11048
11308
|
CONTEXT_FEATURE.LIVE_TIME,
|
|
11049
11309
|
CONTEXT_FEATURE.HISTORY_TIME,
|
|
11050
11310
|
CONTEXT_FEATURE.AGGREGATION,
|
|
11311
|
+
CONTEXT_FEATURE.AUTO_AGGREGATION,
|
|
11051
11312
|
CONTEXT_FEATURE.AUTO_REFRESH,
|
|
11052
11313
|
CONTEXT_FEATURE.REFRESH
|
|
11053
11314
|
]
|
|
@@ -11059,6 +11320,7 @@ const CONTROL_PRESETS = {
|
|
|
11059
11320
|
CONTEXT_FEATURE.HISTORY_TIME,
|
|
11060
11321
|
CONTEXT_FEATURE.AUTO_REFRESH,
|
|
11061
11322
|
CONTEXT_FEATURE.AGGREGATION,
|
|
11323
|
+
CONTEXT_FEATURE.AUTO_AGGREGATION,
|
|
11062
11324
|
CONTEXT_FEATURE.REFRESH
|
|
11063
11325
|
],
|
|
11064
11326
|
config: [
|
|
@@ -11066,12 +11328,14 @@ const CONTROL_PRESETS = {
|
|
|
11066
11328
|
CONTEXT_FEATURE.HISTORY_TIME,
|
|
11067
11329
|
CONTEXT_FEATURE.AUTO_REFRESH,
|
|
11068
11330
|
CONTEXT_FEATURE.AGGREGATION,
|
|
11331
|
+
CONTEXT_FEATURE.AUTO_AGGREGATION,
|
|
11069
11332
|
CONTEXT_FEATURE.REFRESH
|
|
11070
11333
|
],
|
|
11071
11334
|
view_and_config: [
|
|
11072
11335
|
CONTEXT_FEATURE.LIVE_TIME,
|
|
11073
11336
|
CONTEXT_FEATURE.HISTORY_TIME,
|
|
11074
11337
|
CONTEXT_FEATURE.AGGREGATION,
|
|
11338
|
+
CONTEXT_FEATURE.AUTO_AGGREGATION,
|
|
11075
11339
|
CONTEXT_FEATURE.AUTO_REFRESH,
|
|
11076
11340
|
CONTEXT_FEATURE.REFRESH
|
|
11077
11341
|
]
|
|
@@ -11206,6 +11470,9 @@ function controlsToSettings(controls, displayMode, refreshOption) {
|
|
|
11206
11470
|
showAutoRefresh: activeControls.includes(CONTEXT_FEATURE.AUTO_REFRESH),
|
|
11207
11471
|
showRefreshInterval: false,
|
|
11208
11472
|
showAggregation: activeControls.includes(CONTEXT_FEATURE.AGGREGATION),
|
|
11473
|
+
// The "Auto" aggregation option stays visible everywhere but is only selectable for presets
|
|
11474
|
+
// that opt in via AUTO_AGGREGATION (the Data graph widget). Elsewhere it is greyed out.
|
|
11475
|
+
autoModeDisabled: !activeControls.includes(CONTEXT_FEATURE.AUTO_AGGREGATION),
|
|
11209
11476
|
showRefresh: activeControls.includes(CONTEXT_FEATURE.REFRESH) ||
|
|
11210
11477
|
activeControls.includes(CONTEXT_FEATURE.REFRESH_LIVE) ||
|
|
11211
11478
|
activeControls.includes(CONTEXT_FEATURE.REFRESH_HISTORY)
|
|
@@ -11265,11 +11532,15 @@ class ConfigModeControls {
|
|
|
11265
11532
|
onRefreshOptionChange(option) {
|
|
11266
11533
|
this.refreshOption.set(option);
|
|
11267
11534
|
const snapshot = option === REFRESH_OPTION.LIVE ? this.liveState() : this.historyState();
|
|
11535
|
+
const base = snapshot ?? this.config();
|
|
11536
|
+
const isLive = option === REFRESH_OPTION.LIVE;
|
|
11268
11537
|
const context = {
|
|
11269
|
-
...
|
|
11538
|
+
...base,
|
|
11270
11539
|
refreshOption: option,
|
|
11271
11540
|
displayMode: this.displayMode(),
|
|
11272
|
-
aggregation:
|
|
11541
|
+
aggregation: isLive ? null : base.aggregation,
|
|
11542
|
+
autoAggregation: isLive ? null : base.autoAggregation,
|
|
11543
|
+
aggregationFunction: isLive ? null : base.aggregationFunction
|
|
11273
11544
|
};
|
|
11274
11545
|
this.emit(context);
|
|
11275
11546
|
}
|
|
@@ -11320,13 +11591,30 @@ class ConfigModeControls {
|
|
|
11320
11591
|
}
|
|
11321
11592
|
/** Emits configChange if the diff contains changes beyond transient flags. */
|
|
11322
11593
|
emit(context) {
|
|
11323
|
-
const
|
|
11594
|
+
const cleanContext = this.toContextState(context);
|
|
11595
|
+
const diff = this.globalContextUtils.getChangedFields(this.lastEmittedContext(), cleanContext);
|
|
11324
11596
|
const substantiveDiff = { ...diff };
|
|
11325
11597
|
delete substantiveDiff.isGlobalContextReady;
|
|
11326
11598
|
if (Object.keys(substantiveDiff).length === 0)
|
|
11327
11599
|
return;
|
|
11328
|
-
this.lastEmittedContext.set(
|
|
11329
|
-
this.configChange.emit({ context, diff });
|
|
11600
|
+
this.lastEmittedContext.set(cleanContext);
|
|
11601
|
+
this.configChange.emit({ context: cleanContext, diff });
|
|
11602
|
+
}
|
|
11603
|
+
/** Picks only known GlobalContextState fields, dropping any extra properties (e.g. datapoints) that callers may pass at runtime. */
|
|
11604
|
+
toContextState(cfg) {
|
|
11605
|
+
return {
|
|
11606
|
+
dateTimeContext: cfg.dateTimeContext,
|
|
11607
|
+
aggregation: cfg.aggregation,
|
|
11608
|
+
aggregationFunction: cfg.aggregationFunction,
|
|
11609
|
+
autoAggregation: cfg.autoAggregation,
|
|
11610
|
+
isAutoRefreshEnabled: cfg.isAutoRefreshEnabled,
|
|
11611
|
+
refreshInterval: cfg.refreshInterval,
|
|
11612
|
+
refreshOption: cfg.refreshOption,
|
|
11613
|
+
displayMode: cfg.displayMode,
|
|
11614
|
+
source: cfg.source,
|
|
11615
|
+
eventSourceId: cfg.eventSourceId,
|
|
11616
|
+
isGlobalContextReady: cfg.isGlobalContextReady
|
|
11617
|
+
};
|
|
11330
11618
|
}
|
|
11331
11619
|
getGlobalContextState(mode) {
|
|
11332
11620
|
const globalState = this.globalContextEventService.getLatestValue(GLOBAL_CONTEXT_EVENTS.STATE_CHANGE);
|
|
@@ -11336,6 +11624,7 @@ class ConfigModeControls {
|
|
|
11336
11624
|
dateTimeContext: globalState.dateTimeContext,
|
|
11337
11625
|
refreshOption: globalState.refreshOption,
|
|
11338
11626
|
aggregation: globalState.aggregation,
|
|
11627
|
+
autoAggregation: globalState.autoAggregation ?? null,
|
|
11339
11628
|
isAutoRefreshEnabled: globalState.isAutoRefreshEnabled,
|
|
11340
11629
|
refreshInterval: globalState.refreshInterval,
|
|
11341
11630
|
isGlobalContextReady: true
|
|
@@ -11385,7 +11674,7 @@ class ConfigModeControls {
|
|
|
11385
11674
|
></c8y-configuration-controls>
|
|
11386
11675
|
</fieldset>
|
|
11387
11676
|
}
|
|
11388
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ConfigContextSelectorComponent, selector: "c8y-config-context-selector" }, { kind: "component", type: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "intervalOptions", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type:
|
|
11677
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: ConfigContextSelectorComponent, selector: "c8y-config-context-selector" }, { kind: "component", type: ConfigurationControlsComponent, selector: "c8y-configuration-controls", inputs: ["controlsDisplayMode", "settings", "activeMode", "liveContext", "historyContext", "supportedModes", "intervalOptions", "tabsOutletName"], outputs: ["refreshOptionChange", "contextChange", "validationStatus"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i3.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
11389
11678
|
}
|
|
11390
11679
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ConfigModeControls, decorators: [{
|
|
11391
11680
|
type: Component,
|
|
@@ -11451,6 +11740,7 @@ class ContextControlsComponent {
|
|
|
11451
11740
|
this.fb = inject(FormBuilder);
|
|
11452
11741
|
this.aggregationValidationService = inject(AggregationValidationService);
|
|
11453
11742
|
this.globalContextUtils = inject(GlobalContextUtilsService);
|
|
11743
|
+
this.timeSeriesMigrationService = inject(TimeSeriesMigrationService);
|
|
11454
11744
|
this.controls = input(PRESET_NAME.DEFAULT, ...(ngDevMode ? [{ debugName: "controls" }] : /* istanbul ignore next */ []));
|
|
11455
11745
|
this.displayMode = input(GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD, ...(ngDevMode ? [{ debugName: "displayMode" }] : /* istanbul ignore next */ []));
|
|
11456
11746
|
this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
|
|
@@ -11488,6 +11778,12 @@ class ContextControlsComponent {
|
|
|
11488
11778
|
*/
|
|
11489
11779
|
this.refresh = output();
|
|
11490
11780
|
this.lastEmittedState = signal({}, ...(ngDevMode ? [{ debugName: "lastEmittedState" }] : /* istanbul ignore next */ []));
|
|
11781
|
+
this._isAutoModeActive = signal(false, ...(ngDevMode ? [{ debugName: "_isAutoModeActive" }] : /* istanbul ignore next */ []));
|
|
11782
|
+
/**
|
|
11783
|
+
* The "Auto" aggregation option requires the tenant to be migrated to time series
|
|
11784
|
+
* (auto mode uses `aggregationInterval`, unsupported on non-migrated tenants).
|
|
11785
|
+
*/
|
|
11786
|
+
this.isTimeSeriesMigrated = signal(false, ...(ngDevMode ? [{ debugName: "isTimeSeriesMigrated" }] : /* istanbul ignore next */ []));
|
|
11491
11787
|
this.visibleControls = computed(() => {
|
|
11492
11788
|
const cfg = this.config();
|
|
11493
11789
|
if (!cfg)
|
|
@@ -11513,6 +11809,7 @@ class ContextControlsComponent {
|
|
|
11513
11809
|
}
|
|
11514
11810
|
return normalized;
|
|
11515
11811
|
}, ...(ngDevMode ? [{ debugName: "visibleControls" }] : /* istanbul ignore next */ []));
|
|
11812
|
+
this.isAutoModeActive = this._isAutoModeActive.asReadonly();
|
|
11516
11813
|
this.disabledAggregations = computed(() => {
|
|
11517
11814
|
const dateCtx = this.config()?.dateTimeContext;
|
|
11518
11815
|
if (!dateCtx)
|
|
@@ -11537,6 +11834,12 @@ class ContextControlsComponent {
|
|
|
11537
11834
|
});
|
|
11538
11835
|
this.syncConfigToForm();
|
|
11539
11836
|
this.subscribeToFormChanges();
|
|
11837
|
+
effect(() => {
|
|
11838
|
+
this._isAutoModeActive.set(!!this.config()?.autoAggregation);
|
|
11839
|
+
});
|
|
11840
|
+
this.timeSeriesMigrationService
|
|
11841
|
+
.isTimeSeriesMigrated()
|
|
11842
|
+
.then(isMigrated => this.isTimeSeriesMigrated.set(isMigrated));
|
|
11540
11843
|
}
|
|
11541
11844
|
ngOnInit() {
|
|
11542
11845
|
this.emitInitialNonDashboardState();
|
|
@@ -11546,6 +11849,15 @@ class ContextControlsComponent {
|
|
|
11546
11849
|
this.onRefresh();
|
|
11547
11850
|
}
|
|
11548
11851
|
}
|
|
11852
|
+
onAutoModeChange(isAuto) {
|
|
11853
|
+
this._isAutoModeActive.set(isAuto);
|
|
11854
|
+
const context = {
|
|
11855
|
+
...this.config(),
|
|
11856
|
+
aggregation: isAuto ? null : (this.form.get('aggregation')?.value ?? null),
|
|
11857
|
+
autoAggregation: isAuto ? { datapoints: AUTO_AGGREGATION_DATAPOINTS.DEFAULT } : null
|
|
11858
|
+
};
|
|
11859
|
+
this.emitIfChanged(context);
|
|
11860
|
+
}
|
|
11549
11861
|
onRefresh() {
|
|
11550
11862
|
const cfg = this.config();
|
|
11551
11863
|
if (!cfg.dateTimeContext) {
|
|
@@ -11596,7 +11908,12 @@ class ContextControlsComponent {
|
|
|
11596
11908
|
subscribeToFormChanges() {
|
|
11597
11909
|
this.form.valueChanges.pipe(takeUntilDestroyed()).subscribe(value => {
|
|
11598
11910
|
const context = this.clearInvalidAggregation(value);
|
|
11599
|
-
|
|
11911
|
+
// Preserve aggregation-related fields in history mode; clear them when switching to live.
|
|
11912
|
+
const isLive = context.refreshOption === REFRESH_OPTION.LIVE;
|
|
11913
|
+
const cfg = this.config();
|
|
11914
|
+
const autoAgg = isLive ? null : (cfg?.autoAggregation ?? null);
|
|
11915
|
+
const aggregationFunction = isLive ? null : (cfg?.aggregationFunction ?? null);
|
|
11916
|
+
this.emitIfChanged({ ...context, autoAggregation: autoAgg, aggregationFunction });
|
|
11600
11917
|
});
|
|
11601
11918
|
}
|
|
11602
11919
|
/** Clears aggregation if in LIVE mode or invalid for current time range (HISTORY mode). */
|
|
@@ -11634,7 +11951,12 @@ class ContextControlsComponent {
|
|
|
11634
11951
|
data-cy="global-inline-date-context--Aggregation-display"
|
|
11635
11952
|
formControlName="aggregation"
|
|
11636
11953
|
[disabledAggregations]="disabledAggregations()"
|
|
11954
|
+
[autoModeActive]="isAutoModeActive()"
|
|
11955
|
+
[showAutoMode]="
|
|
11956
|
+
visibleControls()?.includes('autoAggregation') && isTimeSeriesMigrated()
|
|
11957
|
+
"
|
|
11637
11958
|
[resetToDefault]="true"
|
|
11959
|
+
(autoModeChange)="onAutoModeChange($event)"
|
|
11638
11960
|
>
|
|
11639
11961
|
</c8y-aggregation-picker>
|
|
11640
11962
|
}
|
|
@@ -11680,7 +12002,7 @@ class ContextControlsComponent {
|
|
|
11680
12002
|
}
|
|
11681
12003
|
</div>
|
|
11682
12004
|
</form>
|
|
11683
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
12005
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DateTimeContextPickerComponent, selector: "c8y-date-time-context-picker", inputs: ["disabled", "shouldDisableInterval", "config", "intervalOptions"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "resetToDefault", "layout", "showAutoMode", "autoModeActive", "autoModeDisabled"], outputs: ["autoModeChange"] }, { kind: "component", type: AutoRefreshControlComponent, selector: "c8y-auto-refresh-control", inputs: ["isAutoRefreshConnected", "autoRefreshSeconds", "disableCounter", "isEnabled", "isLoading"], outputs: ["loadingChange", "refresh"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.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"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
11684
12006
|
}
|
|
11685
12007
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ContextControlsComponent, decorators: [{
|
|
11686
12008
|
type: Component,
|
|
@@ -11704,7 +12026,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
11704
12026
|
data-cy="global-inline-date-context--Aggregation-display"
|
|
11705
12027
|
formControlName="aggregation"
|
|
11706
12028
|
[disabledAggregations]="disabledAggregations()"
|
|
12029
|
+
[autoModeActive]="isAutoModeActive()"
|
|
12030
|
+
[showAutoMode]="
|
|
12031
|
+
visibleControls()?.includes('autoAggregation') && isTimeSeriesMigrated()
|
|
12032
|
+
"
|
|
11707
12033
|
[resetToDefault]="true"
|
|
12034
|
+
(autoModeChange)="onAutoModeChange($event)"
|
|
11708
12035
|
>
|
|
11709
12036
|
</c8y-aggregation-picker>
|
|
11710
12037
|
}
|
|
@@ -12050,8 +12377,18 @@ class GlobalContextConnectorComponent {
|
|
|
12050
12377
|
this.linkedChange.emit(linked);
|
|
12051
12378
|
if (linked) {
|
|
12052
12379
|
const cached = this.eventService.getLatestValue(GLOBAL_CONTEXT_EVENTS.STATE_CHANGE);
|
|
12053
|
-
if (cached)
|
|
12054
|
-
|
|
12380
|
+
if (cached) {
|
|
12381
|
+
// Normalize auto-aggregation fields to null when absent from the cached GC state.
|
|
12382
|
+
// getChangedFields() only iterates the new state's keys, so if the user enabled
|
|
12383
|
+
// autoAggregation locally while unlinked, the diff would be empty (the key is absent
|
|
12384
|
+
// from the GC state) and the widget would not re-sync to the GC aggregation.
|
|
12385
|
+
const normalizedState = {
|
|
12386
|
+
autoAggregation: null,
|
|
12387
|
+
aggregationFunction: null,
|
|
12388
|
+
...cached
|
|
12389
|
+
};
|
|
12390
|
+
this.emitIfChanged(normalizedState);
|
|
12391
|
+
}
|
|
12055
12392
|
}
|
|
12056
12393
|
}
|
|
12057
12394
|
onLocalChange(event) {
|
|
@@ -12332,5 +12669,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
12332
12669
|
* Generated bundle index. Do not edit.
|
|
12333
12670
|
*/
|
|
12334
12671
|
|
|
12335
|
-
export { AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_ICON_TYPE, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, AggregationDisplayComponent, AggregationPickerComponent, AggregationPickerService, AggregationValidationService, AutoRefreshControlComponent, CONTEXT_FEATURE, CONTROL_PRESETS, ConfigContextSelectorComponent, ConfigModeControls, ConfigModeControls as ConfigModeControlsComponent, ConfigurationCollapseComponent, ConfigurationControlsComponent, ContextControlsComponent$1 as ContextControlsComponent, DEFAULT_WIDGET_TEMPLATE, DateContextQueryParamNames, DateTimeContextPickerComponent, DateTimeContextPickerService, DateTimeContextUtil, GLOBAL_CONTEXT_DASHBOARD_PATHS, GLOBAL_CONTEXT_DEFAULTS, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_EVENTS, GLOBAL_CONTEXT_SOURCE, GlobalContextComponent, GlobalContextConfigComponent, GlobalContextConnectorComponent, GlobalContextEventService, GlobalContextFormService, GlobalContextInlineComponent, GlobalContextLinkControlsComponent, GlobalContextModule, GlobalContextNavigationService, GlobalContextQueryService, GlobalContextService, GlobalContextUtilsService, GlobalContextValidationService, GlobalContextWidgetConfigComponent, GlobalContextWidgetWrapperComponent, HistoryModeConfigurationControlsComponent, INTERVALS, INTERVAL_TITLES, IntervalPickerComponent, LIFETIME_INTERVAL, LINK_BTNS_CONFIG, LinkButtonsComponent, LiveModeConfigurationControlsComponent, LocalControlsComponent, PRESET_NAME, PreviewControlsComponent, REFRESH_OPTION, ROUTE_PATHS, RealtimeControlComponent, TIME_DURATION, TIME_INTERVAL, TIME_SPAN_MS, TIMING, TimeRangeDisplayComponent, UI_PRIORITIES, WIDGET_DISPLAY_MODE, WIDGET_FEATURE_MAP, WidgetConfigMigrationService, WidgetControlService, applyModeConstraints, buildAggregationExtensions, buildBaselineControls, buildWidgetControlsFromPresets, controlsToSettings, createAutoRefreshHandlers, createResult, defineWidgetControls, getSupportedModes, guards, isAggregationLinked, isAggregationUnlinked, isAutoRefreshDisabled, isAutoRefreshEnabled, isConfig, isDashboard, isDateTimeContextLinked, isDateTimeContextUnlinked, isHistory, isLive, isViewAndConfig, mergePartialControls, resolveWidgetControlsInput, setAutoRefreshControlsVisibility, setAutoRefreshLinks, updateBothSettings };
|
|
12672
|
+
export { AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_ICON_TYPE, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_POPOVER_TEXT, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, AUTO_AGGREGATION_DATAPOINTS, AUTO_AGGREGATION_TEXT, AUTO_AGGREGATION_TEXT_LONG, AggregationDisplayComponent, AggregationPickerComponent, AggregationPickerService, AggregationValidationService, AutoRefreshControlComponent, CONTEXT_FEATURE, CONTROL_PRESETS, ConfigContextSelectorComponent, ConfigModeControls, ConfigModeControls as ConfigModeControlsComponent, ConfigurationCollapseComponent, ConfigurationControlsComponent, ContextControlsComponent$1 as ContextControlsComponent, DEFAULT_WIDGET_TEMPLATE, DateContextQueryParamNames, DateTimeContextPickerComponent, DateTimeContextPickerService, DateTimeContextUtil, GLOBAL_CONTEXT_DASHBOARD_PATHS, GLOBAL_CONTEXT_DEFAULTS, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_EVENTS, GLOBAL_CONTEXT_SOURCE, GlobalContextComponent, GlobalContextConfigComponent, GlobalContextConnectorComponent, GlobalContextEventService, GlobalContextFormService, GlobalContextInlineComponent, GlobalContextLinkControlsComponent, GlobalContextModule, GlobalContextNavigationService, GlobalContextQueryService, GlobalContextService, GlobalContextUtilsService, GlobalContextValidationService, GlobalContextWidgetConfigComponent, GlobalContextWidgetWrapperComponent, HistoryModeConfigurationControlsComponent, INTERVALS, INTERVAL_TITLES, IntervalPickerComponent, LIFETIME_INTERVAL, LINK_BTNS_CONFIG, LinkButtonsComponent, LiveModeConfigurationControlsComponent, LocalControlsComponent, PRESET_NAME, PreviewControlsComponent, REFRESH_OPTION, ROUTE_PATHS, RealtimeControlComponent, TIME_DURATION, TIME_INTERVAL, TIME_SPAN_MS, TIMING, TimeRangeDisplayComponent, TimeSeriesMigrationService, UI_PRIORITIES, WIDGET_DISPLAY_MODE, WIDGET_FEATURE_MAP, WidgetConfigMigrationService, WidgetControlService, applyModeConstraints, buildAggregationExtensions, buildBaselineControls, buildWidgetControlsFromPresets, controlsToSettings, createAutoRefreshHandlers, createResult, defineWidgetControls, getSupportedModes, guards, isAggregationLinked, isAggregationUnlinked, isAutoRefreshDisabled, isAutoRefreshEnabled, isConfig, isDashboard, isDateTimeContextLinked, isDateTimeContextUnlinked, isHistory, isLive, isViewAndConfig, mergePartialControls, resolveWidgetControlsInput, setAutoRefreshControlsVisibility, setAutoRefreshLinks, updateBothSettings };
|
|
12336
12673
|
//# sourceMappingURL=c8y-ngx-components-global-context.mjs.map
|