@c8y/ngx-components 1024.1.8 → 1024.5.1
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-bookmarks.mjs +33 -23
- package/fesm2022/c8y-ngx-components-bookmarks.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +2 -2
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +65 -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-device-profile.mjs +27 -9
- package/fesm2022/c8y-ngx-components-device-profile.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-protocol-opcua.mjs +9 -11
- package/fesm2022/c8y-ngx-components-protocol-opcua.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-remote-access-data.mjs +43 -0
- package/fesm2022/c8y-ngx-components-remote-access-data.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.mjs +17 -3
- package/fesm2022/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-remote-access-terminal-viewer.mjs +179 -41
- package/fesm2022/c8y-ngx-components-remote-access-terminal-viewer.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-firmware.mjs +5 -4
- package/fesm2022/c8y-ngx-components-repository-firmware.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-repository-software.mjs +10 -4
- package/fesm2022/c8y-ngx-components-repository-software.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-trusted-certificates.mjs +5 -4
- package/fesm2022/c8y-ngx-components-trusted-certificates.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +6 -5
- package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.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 +109 -36
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/de.po +141 -13
- package/locales/es.po +141 -13
- package/locales/fr.po +141 -13
- package/locales/ja_JP.po +140 -14
- package/locales/ko.po +141 -13
- package/locales/locales.pot +139 -11
- package/locales/nl.po +141 -13
- package/locales/pl.po +141 -13
- package/locales/pt_BR.po +141 -13
- package/locales/zh_CN.po +141 -13
- package/locales/zh_TW.po +141 -13
- package/package.json +1 -1
- package/types/c8y-ngx-components-bookmarks.d.ts +7 -7
- package/types/c8y-ngx-components-bookmarks.d.ts.map +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-device-profile.d.ts +5 -2
- package/types/c8y-ngx-components-device-profile.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-protocol-opcua.d.ts.map +1 -1
- package/types/c8y-ngx-components-remote-access-data.d.ts +19 -0
- package/types/c8y-ngx-components-remote-access-data.d.ts.map +1 -1
- package/types/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.d.ts +10 -3
- package/types/c8y-ngx-components-remote-access-ssh-remote-access-ssh-endpoint-modal.d.ts.map +1 -1
- package/types/c8y-ngx-components-remote-access-terminal-viewer.d.ts +20 -2
- package/types/c8y-ngx-components-remote-access-terminal-viewer.d.ts.map +1 -1
- package/types/c8y-ngx-components-repository-firmware.d.ts.map +1 -1
- package/types/c8y-ngx-components-repository-software.d.ts +2 -0
- package/types/c8y-ngx-components-repository-software.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-trusted-certificates.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-asset-table.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 +55 -12
- package/types/c8y-ngx-components.d.ts.map +1 -1
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, inject, DestroyRef, model, ViewChild, Input, Component } from '@angular/core';
|
|
2
|
+
import { Injectable, inject, DestroyRef, signal, model, ViewChild, Input, Component } from '@angular/core';
|
|
3
3
|
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import * as i3 from '@angular/forms';
|
|
5
5
|
import { FormBuilder } from '@angular/forms';
|
|
6
6
|
import * as i1 from '@c8y/ngx-components';
|
|
7
7
|
import { AGGREGATION_LIMITS, CoreModule, DateTimePickerModule, AggregationPickerComponent } from '@c8y/ngx-components';
|
|
8
|
-
import { RealtimeControlComponent } from '@c8y/ngx-components/global-context';
|
|
8
|
+
import { TimeSeriesMigrationService, AUTO_AGGREGATION_DATAPOINTS, AGGREGATION_POPOVER_TEXT, TIMING, RealtimeControlComponent } from '@c8y/ngx-components/global-context';
|
|
9
9
|
import { INTERVALS, TimeSpanInMs, INTERVAL_TITLES, IntervalPickerComponent } from '@c8y/ngx-components/interval-picker';
|
|
10
|
+
import { gettext } from '@c8y/ngx-components/gettext';
|
|
10
11
|
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
|
|
11
12
|
import * as i4 from 'ngx-bootstrap/dropdown';
|
|
12
13
|
import { BsDropdownModule, BsDropdownDirective } from 'ngx-bootstrap/dropdown';
|
|
13
14
|
import * as i5 from 'ngx-bootstrap/tooltip';
|
|
14
15
|
import { TooltipModule } from 'ngx-bootstrap/tooltip';
|
|
15
|
-
import
|
|
16
|
+
import * as i6 from 'ngx-bootstrap/popover';
|
|
17
|
+
import { PopoverModule } from 'ngx-bootstrap/popover';
|
|
18
|
+
import { debounceTime, interval } from 'rxjs';
|
|
16
19
|
import { aggregationType } from '@c8y/client';
|
|
17
20
|
import * as i2 from '@angular/common';
|
|
18
21
|
|
|
@@ -98,6 +101,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
98
101
|
// TODO: REMOVE THIS FILE
|
|
99
102
|
class TimeContextComponent {
|
|
100
103
|
#destroyRef;
|
|
104
|
+
#timeSeriesMigrationService;
|
|
101
105
|
constructor(widgetTimeContextDateRangeService) {
|
|
102
106
|
this.widgetTimeContextDateRangeService = widgetTimeContextDateRangeService;
|
|
103
107
|
this.timeContext = {};
|
|
@@ -106,13 +110,27 @@ class TimeContextComponent {
|
|
|
106
110
|
showSeconds: false,
|
|
107
111
|
showSpinners: false
|
|
108
112
|
};
|
|
113
|
+
this.enableAutoAggregation = false;
|
|
109
114
|
this.datapointExplorerService = inject(DatapointExplorerService);
|
|
110
115
|
this.formBuilder = inject(FormBuilder);
|
|
111
116
|
this.#destroyRef = inject(DestroyRef);
|
|
117
|
+
this.#timeSeriesMigrationService = inject(TimeSeriesMigrationService);
|
|
112
118
|
this.DATE_FORMAT = 'short';
|
|
113
119
|
this.INTERVAL_TITLES = INTERVAL_TITLES;
|
|
114
120
|
this.REALTIME_INTERVAL = 1000;
|
|
121
|
+
this.AUTO_AGGREGATION_DATAPOINTS = AUTO_AGGREGATION_DATAPOINTS;
|
|
122
|
+
this.AGGREGATION_POPOVER = AGGREGATION_POPOVER_TEXT;
|
|
123
|
+
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.');
|
|
124
|
+
/** Whether auto-aggregation mode is active. */
|
|
125
|
+
this.isAutoModeActive = signal(false, ...(ngDevMode ? [{ debugName: "isAutoModeActive" }] : /* istanbul ignore next */ []));
|
|
126
|
+
/**
|
|
127
|
+
* The "Auto" aggregation option requires the tenant to be migrated to time series
|
|
128
|
+
* (auto mode uses `aggregationInterval`, unsupported on non-migrated tenants).
|
|
129
|
+
*/
|
|
130
|
+
this.isTimeSeriesMigrated = signal(false, ...(ngDevMode ? [{ debugName: "isTimeSeriesMigrated" }] : /* istanbul ignore next */ []));
|
|
115
131
|
this.form = this.createForm(this.datapointExplorerService.getDefaultContext());
|
|
132
|
+
/** Last datapoints value applied to the context; restored when the field is left empty. */
|
|
133
|
+
this.lastAppliedDatapoints = AUTO_AGGREGATION_DATAPOINTS.DEFAULT;
|
|
116
134
|
this.valuesSignal = toSignal(this.form.controls.currentDateContextFromDate.valueChanges, {
|
|
117
135
|
initialValue: this.form.controls.currentDateContextFromDate.value
|
|
118
136
|
});
|
|
@@ -123,9 +141,14 @@ class TimeContextComponent {
|
|
|
123
141
|
const context = this.datapointExplorerService.getDefaultContext(this.timeContext);
|
|
124
142
|
const { disabledAggregations } = this.datapointExplorerService.calculateAggregation(context.date, context.aggregation);
|
|
125
143
|
this.disabledAggregations = disabledAggregations;
|
|
144
|
+
this.#timeSeriesMigrationService
|
|
145
|
+
.isTimeSeriesMigrated()
|
|
146
|
+
.then(isMigrated => this.isTimeSeriesMigrated.set(isMigrated));
|
|
126
147
|
this.subscribeToIntervalChange();
|
|
127
148
|
this.subscribeToRealtimeChange();
|
|
128
149
|
this.subscribeToAggregationChange();
|
|
150
|
+
this.subscribeToDatapointsChange();
|
|
151
|
+
this.subscribeToKeepDataOnZoomInChange();
|
|
129
152
|
}
|
|
130
153
|
ngOnChanges(changes) {
|
|
131
154
|
if (changes.changedDateContext && changes.changedDateContext.currentValue) {
|
|
@@ -141,23 +164,42 @@ class TimeContextComponent {
|
|
|
141
164
|
newDateTo !== currentFormValues.currentDateContextToDate ||
|
|
142
165
|
this.changedDateContext.interval !== currentFormValues.currentDateContextInterval ||
|
|
143
166
|
this.changedDateContext.realtime !== currentFormValues.realtime ||
|
|
144
|
-
this.changedDateContext.aggregation !== currentFormValues.aggregation
|
|
167
|
+
this.changedDateContext.aggregation !== currentFormValues.aggregation ||
|
|
168
|
+
!!this.changedDateContext.autoAggregation !== currentFormValues.autoAggregationEnabled;
|
|
145
169
|
if (!hasActualChanges) {
|
|
146
170
|
return;
|
|
147
171
|
}
|
|
148
172
|
// Don't emit when update comes from parent (avoid infinite loop)
|
|
173
|
+
const incomingAutoAggregation = this.changedDateContext.autoAggregation ?? null;
|
|
174
|
+
this.isAutoModeActive.set(!!incomingAutoAggregation);
|
|
149
175
|
this.update({
|
|
150
176
|
date: [this.changedDateContext.dateFrom, this.changedDateContext.dateTo],
|
|
151
177
|
interval: this.changedDateContext.interval,
|
|
152
178
|
realtime: this.changedDateContext.realtime || false,
|
|
153
|
-
aggregation: this.changedDateContext.aggregation
|
|
179
|
+
aggregation: incomingAutoAggregation ? null : this.changedDateContext.aggregation,
|
|
180
|
+
autoAggregation: incomingAutoAggregation
|
|
154
181
|
}, false);
|
|
155
182
|
if (this.changedDateContext.realtime) {
|
|
156
183
|
this.form.controls.aggregation.disable();
|
|
157
184
|
}
|
|
158
185
|
}
|
|
159
186
|
}
|
|
187
|
+
/** Called by the aggregation picker's (autoModeChange) output. */
|
|
188
|
+
onAutoModeChange(isAuto) {
|
|
189
|
+
this.isAutoModeActive.set(isAuto);
|
|
190
|
+
this.update({
|
|
191
|
+
date: [
|
|
192
|
+
new Date(this.form.value.currentDateContextFromDate),
|
|
193
|
+
new Date(this.form.value.currentDateContextToDate)
|
|
194
|
+
],
|
|
195
|
+
interval: this.form.value.currentDateContextInterval,
|
|
196
|
+
realtime: this.form.value.realtime,
|
|
197
|
+
aggregation: isAuto ? null : this.form.value.aggregation,
|
|
198
|
+
autoAggregation: isAuto ? this.buildAutoAggregationConfig() : null
|
|
199
|
+
});
|
|
200
|
+
}
|
|
160
201
|
applyDatetimeContext() {
|
|
202
|
+
const isAuto = this.isAutoModeActive();
|
|
161
203
|
this.update({
|
|
162
204
|
date: [
|
|
163
205
|
new Date(this.form.controls.temporaryUserSelectedFromDate.value),
|
|
@@ -165,7 +207,8 @@ class TimeContextComponent {
|
|
|
165
207
|
],
|
|
166
208
|
interval: 'custom',
|
|
167
209
|
realtime: this.form.value.realtime,
|
|
168
|
-
aggregation: this.form.value.aggregation
|
|
210
|
+
aggregation: isAuto ? null : this.form.value.aggregation,
|
|
211
|
+
autoAggregation: isAuto ? this.buildAutoAggregationConfig() : null
|
|
169
212
|
});
|
|
170
213
|
}
|
|
171
214
|
stopRealtime() {
|
|
@@ -202,7 +245,8 @@ class TimeContextComponent {
|
|
|
202
245
|
date,
|
|
203
246
|
interval,
|
|
204
247
|
realtime: this.form.value.realtime,
|
|
205
|
-
aggregation: this.form.value.aggregation
|
|
248
|
+
aggregation: this.isAutoModeActive() ? null : this.form.value.aggregation,
|
|
249
|
+
autoAggregation: this.isAutoModeActive() ? this.buildAutoAggregationConfig() : null
|
|
206
250
|
});
|
|
207
251
|
});
|
|
208
252
|
}
|
|
@@ -223,6 +267,10 @@ class TimeContextComponent {
|
|
|
223
267
|
this.form.controls.aggregation.valueChanges
|
|
224
268
|
.pipe(takeUntilDestroyed(this.#destroyRef))
|
|
225
269
|
.subscribe(aggregation => {
|
|
270
|
+
// Skip during auto mode transitions — onAutoModeChange handles the update
|
|
271
|
+
if (this.isAutoModeActive()) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
226
274
|
this.update({
|
|
227
275
|
date: [
|
|
228
276
|
new Date(this.form.value.currentDateContextFromDate),
|
|
@@ -230,10 +278,73 @@ class TimeContextComponent {
|
|
|
230
278
|
],
|
|
231
279
|
interval: this.form.value.currentDateContextInterval,
|
|
232
280
|
realtime: this.form.value.realtime,
|
|
233
|
-
aggregation
|
|
281
|
+
aggregation,
|
|
282
|
+
autoAggregation: null
|
|
234
283
|
});
|
|
235
284
|
});
|
|
236
285
|
}
|
|
286
|
+
subscribeToDatapointsChange() {
|
|
287
|
+
this.form.controls.autoAggregationDatapoints.valueChanges
|
|
288
|
+
.pipe(takeUntilDestroyed(this.#destroyRef), debounceTime(TIMING.TYPING_DEBOUNCE))
|
|
289
|
+
.subscribe(datapoints => {
|
|
290
|
+
if (!this.isAutoModeActive()) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
// Skip while the field is empty or out of range — the user is still typing. Rewriting
|
|
294
|
+
// or emitting a clamped value here would snap the field back mid-edit;
|
|
295
|
+
// commitDatapoints() (blur) commits a valid value instead.
|
|
296
|
+
if (!this.isValidDatapoints(datapoints)) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
this.emitAutoAggregationUpdate();
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
isValidDatapoints(value) {
|
|
303
|
+
return (typeof value === 'number' &&
|
|
304
|
+
!Number.isNaN(value) &&
|
|
305
|
+
value >= AUTO_AGGREGATION_DATAPOINTS.MIN &&
|
|
306
|
+
value <= AUTO_AGGREGATION_DATAPOINTS.MAX);
|
|
307
|
+
}
|
|
308
|
+
clampToDatapointsBounds(value) {
|
|
309
|
+
return Math.min(AUTO_AGGREGATION_DATAPOINTS.MAX, Math.max(AUTO_AGGREGATION_DATAPOINTS.MIN, value));
|
|
310
|
+
}
|
|
311
|
+
subscribeToKeepDataOnZoomInChange() {
|
|
312
|
+
this.form.controls.autoAggregationKeepDataOnZoomIn.valueChanges
|
|
313
|
+
.pipe(takeUntilDestroyed(this.#destroyRef))
|
|
314
|
+
.subscribe(() => {
|
|
315
|
+
if (!this.isAutoModeActive()) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
this.emitAutoAggregationUpdate();
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
emitAutoAggregationUpdate() {
|
|
322
|
+
this.update({
|
|
323
|
+
date: [
|
|
324
|
+
new Date(this.form.value.currentDateContextFromDate),
|
|
325
|
+
new Date(this.form.value.currentDateContextToDate)
|
|
326
|
+
],
|
|
327
|
+
interval: this.form.value.currentDateContextInterval,
|
|
328
|
+
realtime: this.form.value.realtime,
|
|
329
|
+
aggregation: null,
|
|
330
|
+
autoAggregation: this.buildAutoAggregationConfig()
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Builds the auto-aggregation config from the current form state, clamped to the allowed
|
|
335
|
+
* range. Falls back to the last applied value while the field is empty (mid-edit).
|
|
336
|
+
*
|
|
337
|
+
* Reads control values instead of `this.form.value`: a control's valueChanges fires before
|
|
338
|
+
* the parent group recomputes its cached value, so the group value is stale inside the
|
|
339
|
+
* subscriptions that call this method.
|
|
340
|
+
*/
|
|
341
|
+
buildAutoAggregationConfig() {
|
|
342
|
+
const datapoints = this.clampToDatapointsBounds(this.form.controls.autoAggregationDatapoints.value ?? this.lastAppliedDatapoints);
|
|
343
|
+
return {
|
|
344
|
+
datapoints,
|
|
345
|
+
keepDataOnZoomIn: this.form.controls.autoAggregationKeepDataOnZoomIn.value ?? true
|
|
346
|
+
};
|
|
347
|
+
}
|
|
237
348
|
onRealtimeValueChange(realtime) {
|
|
238
349
|
let dateTimeContext;
|
|
239
350
|
if (this.form.value.currentDateContextInterval !== 'custom') {
|
|
@@ -246,11 +357,13 @@ class TimeContextComponent {
|
|
|
246
357
|
const dateFrom = new Date(dateTo.valueOf() - currentTimeSpanInMs);
|
|
247
358
|
dateTimeContext = [dateFrom, dateTo];
|
|
248
359
|
}
|
|
360
|
+
this.isAutoModeActive.set(false);
|
|
249
361
|
this.update({
|
|
250
362
|
date: dateTimeContext,
|
|
251
363
|
interval: this.form.value.currentDateContextInterval,
|
|
252
364
|
realtime,
|
|
253
|
-
aggregation: null
|
|
365
|
+
aggregation: null,
|
|
366
|
+
autoAggregation: null
|
|
254
367
|
});
|
|
255
368
|
}
|
|
256
369
|
startRealtime() {
|
|
@@ -274,10 +387,10 @@ class TimeContextComponent {
|
|
|
274
387
|
}, false); // Don't emit during automatic realtime ticks
|
|
275
388
|
});
|
|
276
389
|
}
|
|
277
|
-
update({ date, interval, realtime, aggregation }, shouldEmit = true) {
|
|
278
|
-
const { selectedAggregation, disabledAggregations } = this.datapointExplorerService.calculateAggregation(date, aggregation);
|
|
390
|
+
update({ date, interval, realtime, aggregation, autoAggregation = null }, shouldEmit = true) {
|
|
391
|
+
const { selectedAggregation, disabledAggregations } = this.datapointExplorerService.calculateAggregation(date, autoAggregation ? null : aggregation);
|
|
279
392
|
this.disabledAggregations = disabledAggregations;
|
|
280
|
-
this.updateFormValues({ date, interval, realtime, aggregation: selectedAggregation }, shouldEmit);
|
|
393
|
+
this.updateFormValues({ date, interval, realtime, aggregation: selectedAggregation, autoAggregation }, shouldEmit);
|
|
281
394
|
}
|
|
282
395
|
createForm(context) {
|
|
283
396
|
return this.formBuilder.group({
|
|
@@ -287,10 +400,13 @@ class TimeContextComponent {
|
|
|
287
400
|
currentDateContextToDate: context.date[1].toISOString(),
|
|
288
401
|
currentDateContextInterval: context.interval || 'custom',
|
|
289
402
|
realtime: context.realtime,
|
|
290
|
-
aggregation: context.aggregation
|
|
403
|
+
aggregation: context.aggregation,
|
|
404
|
+
autoAggregationEnabled: false,
|
|
405
|
+
autoAggregationDatapoints: AUTO_AGGREGATION_DATAPOINTS.DEFAULT,
|
|
406
|
+
autoAggregationKeepDataOnZoomIn: true
|
|
291
407
|
});
|
|
292
408
|
}
|
|
293
|
-
updateFormValues({ date, interval, realtime, aggregation }, shouldEmit = true) {
|
|
409
|
+
updateFormValues({ date, interval, realtime, aggregation, autoAggregation = null }, shouldEmit = true) {
|
|
294
410
|
const newFormValues = {
|
|
295
411
|
temporaryUserSelectedFromDate: date[0].toISOString(),
|
|
296
412
|
temporaryUserSelectedToDate: date[1].toISOString(),
|
|
@@ -298,17 +414,24 @@ class TimeContextComponent {
|
|
|
298
414
|
currentDateContextToDate: date[1].toISOString(),
|
|
299
415
|
realtime,
|
|
300
416
|
currentDateContextInterval: interval || 'custom',
|
|
301
|
-
aggregation: aggregation || null
|
|
417
|
+
aggregation: autoAggregation ? null : aggregation || null,
|
|
418
|
+
autoAggregation
|
|
302
419
|
};
|
|
303
420
|
if (shouldEmit) {
|
|
304
421
|
this.context.set(newFormValues);
|
|
305
422
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
423
|
+
if (autoAggregation?.datapoints != null) {
|
|
424
|
+
this.lastAppliedDatapoints = this.clampToDatapointsBounds(autoAggregation.datapoints);
|
|
425
|
+
}
|
|
426
|
+
this.form.patchValue({
|
|
427
|
+
...newFormValues,
|
|
428
|
+
autoAggregationEnabled: !!autoAggregation,
|
|
429
|
+
autoAggregationDatapoints: autoAggregation?.datapoints ?? this.form.value.autoAggregationDatapoints,
|
|
430
|
+
autoAggregationKeepDataOnZoomIn: autoAggregation?.keepDataOnZoomIn ?? this.form.value.autoAggregationKeepDataOnZoomIn
|
|
431
|
+
}, { emitEvent: false });
|
|
309
432
|
}
|
|
310
433
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TimeContextComponent, deps: [{ token: i1.WidgetTimeContextDateRangeService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
311
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TimeContextComponent, isStandalone: true, selector: "c8y-time-context", inputs: { changedDateContext: { classPropertyName: "changedDateContext", publicName: "changedDateContext", isSignal: false, isRequired: false, transformFunction: null }, controlsAvailable: { classPropertyName: "controlsAvailable", publicName: "controlsAvailable", isSignal: false, isRequired: false, transformFunction: null }, timeContext: { classPropertyName: "timeContext", publicName: "timeContext", isSignal: false, isRequired: false, transformFunction: null }, timePickerConfig: { classPropertyName: "timePickerConfig", publicName: "timePickerConfig", isSignal: false, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { context: "contextChange" }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (controlsAvailable) {\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n} @else {\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n}\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n @if (date) {\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-wide dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n @if (form.controls.currentDateContextInterval.value === 'custom') {\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"\n form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\n \"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n }\n </ul>\n </div>\n }\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n @if (controlsAvailable ? controlsAvailable.aggregation : true) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n }\n </div>\n </form>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "component", type: i1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i1.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "component", type: i1.AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations"] }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i4.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i4.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i4.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.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: "component", type: IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS"] }, { kind: "component", type: RealtimeControlComponent, selector: "c8y-realtime-control" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i1.DatePipe, name: "c8yDate" }] }); }
|
|
434
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TimeContextComponent, isStandalone: true, selector: "c8y-time-context", inputs: { changedDateContext: { classPropertyName: "changedDateContext", publicName: "changedDateContext", isSignal: false, isRequired: false, transformFunction: null }, controlsAvailable: { classPropertyName: "controlsAvailable", publicName: "controlsAvailable", isSignal: false, isRequired: false, transformFunction: null }, timeContext: { classPropertyName: "timeContext", publicName: "timeContext", isSignal: false, isRequired: false, transformFunction: null }, timePickerConfig: { classPropertyName: "timePickerConfig", publicName: "timePickerConfig", isSignal: false, isRequired: false, transformFunction: null }, enableAutoAggregation: { classPropertyName: "enableAutoAggregation", publicName: "enableAutoAggregation", isSignal: false, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { context: "contextChange" }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (controlsAvailable) {\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n} @else {\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n itemClass=\"navbar-form\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n}\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n @if (date) {\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-8\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-muted fit-w text-10 l-h-1\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-bold text-12 fit-w l-h-1 text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-wide dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n @if (form.controls.currentDateContextInterval.value === 'custom') {\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"\n form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\n \"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n }\n </ul>\n </div>\n }\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n @if (enableAutoAggregation && isTimeSeriesMigrated()) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [showAutoMode]=\"true\"\n [autoModeActive]=\"isAutoModeActive()\"\n [autoPoints]=\"form.value.autoAggregationDatapoints\"\n [autoKeepPointCount]=\"form.value.autoAggregationKeepDataOnZoomIn\"\n [disabledAggregations]=\"disabledAggregations\"\n (autoModeChange)=\"onAutoModeChange($event)\"\n >\n <div\n class=\"d-col\"\n autoAggregationOptions\n >\n <div class=\"d-flex a-i-center gap-8\">\n <label class=\"m-b-0 m-r-8\">\n {{ 'Points per chart' | translate }}\n </label>\n <input\n class=\"form-control input-sm\"\n style=\"width: 80px\"\n [attr.title]=\"\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 \"\n [attr.aria-label]=\"'Points per chart' | translate\"\n type=\"number\"\n [min]=\"AUTO_AGGREGATION_DATAPOINTS.MIN\"\n [max]=\"AUTO_AGGREGATION_DATAPOINTS.MAX\"\n [step]=\"AUTO_AGGREGATION_DATAPOINTS.STEP\"\n [formControl]=\"form.controls.autoAggregationDatapoints\"\n />\n </div>\n <label\n class=\"c8y-switch m-b-0 m-t-8 text-nowrap\"\n [title]=\"'Keep point count on zoom' | translate\"\n >\n <input\n type=\"checkbox\"\n [formControl]=\"form.controls.autoAggregationKeepDataOnZoomIn\"\n data-cy=\"time-context--auto-aggregation-keep-data-on-zoom-in\"\n />\n <span></span>\n <span class=\"text-12\">{{ '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 ></button>\n </label>\n </div>\n </c8y-aggregation-picker>\n } @else if (\n enableAutoAggregation || (controlsAvailable ? controlsAvailable.aggregation : true)\n ) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n }\n\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 ></button>\n </div>\n </form>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "component", type: i1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.MinValidationDirective, selector: "[min]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidationDirective, selector: "[max]", inputs: ["max"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i3.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i1.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "component", type: i1.AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations", "autoPoints", "autoKeepPointCount", "showAutoMode", "autoModeActive"], outputs: ["autoModeChange"] }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i4.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i4.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i4.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.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: PopoverModule }, { kind: "directive", type: i6.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: IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS"] }, { kind: "component", type: RealtimeControlComponent, selector: "c8y-realtime-control" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i1.DatePipe, name: "c8yDate" }] }); }
|
|
312
435
|
}
|
|
313
436
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TimeContextComponent, decorators: [{
|
|
314
437
|
type: Component,
|
|
@@ -319,9 +442,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
319
442
|
BsDropdownModule,
|
|
320
443
|
AggregationPickerComponent,
|
|
321
444
|
TooltipModule,
|
|
445
|
+
PopoverModule,
|
|
322
446
|
IntervalPickerComponent,
|
|
323
447
|
RealtimeControlComponent
|
|
324
|
-
], template: "@if (controlsAvailable) {\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n} @else {\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n}\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n @if (date) {\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-wide dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n @if (form.controls.currentDateContextInterval.value === 'custom') {\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"\n form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\n \"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n }\n </ul>\n </div>\n }\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n @if (controlsAvailable ? controlsAvailable.aggregation : true) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n }\n </div>\n </form>\n</ng-template>\n" }]
|
|
448
|
+
], template: "@if (controlsAvailable) {\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n} @else {\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n itemClass=\"navbar-form\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n}\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n @if (date) {\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-8\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-muted fit-w text-10 l-h-1\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-bold text-12 fit-w l-h-1 text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-wide dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n @if (form.controls.currentDateContextInterval.value === 'custom') {\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"\n form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\n \"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n }\n </ul>\n </div>\n }\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n @if (enableAutoAggregation && isTimeSeriesMigrated()) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [showAutoMode]=\"true\"\n [autoModeActive]=\"isAutoModeActive()\"\n [autoPoints]=\"form.value.autoAggregationDatapoints\"\n [autoKeepPointCount]=\"form.value.autoAggregationKeepDataOnZoomIn\"\n [disabledAggregations]=\"disabledAggregations\"\n (autoModeChange)=\"onAutoModeChange($event)\"\n >\n <div\n class=\"d-col\"\n autoAggregationOptions\n >\n <div class=\"d-flex a-i-center gap-8\">\n <label class=\"m-b-0 m-r-8\">\n {{ 'Points per chart' | translate }}\n </label>\n <input\n class=\"form-control input-sm\"\n style=\"width: 80px\"\n [attr.title]=\"\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 \"\n [attr.aria-label]=\"'Points per chart' | translate\"\n type=\"number\"\n [min]=\"AUTO_AGGREGATION_DATAPOINTS.MIN\"\n [max]=\"AUTO_AGGREGATION_DATAPOINTS.MAX\"\n [step]=\"AUTO_AGGREGATION_DATAPOINTS.STEP\"\n [formControl]=\"form.controls.autoAggregationDatapoints\"\n />\n </div>\n <label\n class=\"c8y-switch m-b-0 m-t-8 text-nowrap\"\n [title]=\"'Keep point count on zoom' | translate\"\n >\n <input\n type=\"checkbox\"\n [formControl]=\"form.controls.autoAggregationKeepDataOnZoomIn\"\n data-cy=\"time-context--auto-aggregation-keep-data-on-zoom-in\"\n />\n <span></span>\n <span class=\"text-12\">{{ '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 ></button>\n </label>\n </div>\n </c8y-aggregation-picker>\n } @else if (\n enableAutoAggregation || (controlsAvailable ? controlsAvailable.aggregation : true)\n ) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n }\n\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 ></button>\n </div>\n </form>\n</ng-template>\n" }]
|
|
325
449
|
}], ctorParameters: () => [{ type: i1.WidgetTimeContextDateRangeService }], propDecorators: { changedDateContext: [{
|
|
326
450
|
type: Input
|
|
327
451
|
}], controlsAvailable: [{
|
|
@@ -330,6 +454,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
330
454
|
type: Input
|
|
331
455
|
}], timePickerConfig: [{
|
|
332
456
|
type: Input
|
|
457
|
+
}], enableAutoAggregation: [{
|
|
458
|
+
type: Input
|
|
333
459
|
}], dropdown: [{
|
|
334
460
|
type: ViewChild,
|
|
335
461
|
args: [BsDropdownDirective]
|