@c8y/ngx-components 1024.15.13 → 1024.16.5

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.
Files changed (60) hide show
  1. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs +303 -63
  2. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs.map +1 -1
  3. package/fesm2022/c8y-ngx-components-ai-agents-html.mjs +9 -0
  4. package/fesm2022/c8y-ngx-components-ai-agents-html.mjs.map +1 -1
  5. package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs +4 -0
  6. package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs.map +1 -1
  7. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs +394 -52
  8. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs.map +1 -1
  9. package/fesm2022/c8y-ngx-components-ai.mjs +329 -19
  10. package/fesm2022/c8y-ngx-components-ai.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +7 -1
  12. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  13. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +95 -76
  14. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
  15. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +92 -47
  16. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
  17. package/fesm2022/c8y-ngx-components-echart.mjs +39 -12
  18. package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
  19. package/fesm2022/c8y-ngx-components-time-context.mjs +13 -9
  20. package/fesm2022/c8y-ngx-components-time-context.mjs.map +1 -1
  21. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs +3 -2
  22. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs.map +1 -1
  23. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +4 -6
  24. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs.map +1 -1
  25. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs +3 -2
  26. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs.map +1 -1
  27. package/fesm2022/c8y-ngx-components.mjs +65 -14
  28. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  29. package/locales/de.po +147 -16
  30. package/locales/es.po +143 -11
  31. package/locales/fr.po +459 -324
  32. package/locales/ja_JP.po +143 -11
  33. package/locales/ko.po +143 -11
  34. package/locales/locales.pot +139 -10
  35. package/locales/nl.po +143 -11
  36. package/locales/pl.po +143 -11
  37. package/locales/pt_BR.po +143 -11
  38. package/locales/zh_CN.po +143 -11
  39. package/locales/zh_TW.po +143 -11
  40. package/package.json +1 -1
  41. package/types/c8y-ngx-components-ai-agent-chat.d.ts +111 -4
  42. package/types/c8y-ngx-components-ai-agent-chat.d.ts.map +1 -1
  43. package/types/c8y-ngx-components-ai-agents-html.d.ts.map +1 -1
  44. package/types/c8y-ngx-components-ai-agents-scada.d.ts.map +1 -1
  45. package/types/c8y-ngx-components-ai-ai-chat.d.ts +224 -10
  46. package/types/c8y-ngx-components-ai-ai-chat.d.ts.map +1 -1
  47. package/types/c8y-ngx-components-ai.d.ts +176 -6
  48. package/types/c8y-ngx-components-ai.d.ts.map +1 -1
  49. package/types/c8y-ngx-components-context-dashboard.d.ts.map +1 -1
  50. package/types/c8y-ngx-components-datapoint-explorer-view.d.ts +7 -2
  51. package/types/c8y-ngx-components-datapoint-explorer-view.d.ts.map +1 -1
  52. package/types/c8y-ngx-components-datapoint-selector.d.ts +63 -50
  53. package/types/c8y-ngx-components-datapoint-selector.d.ts.map +1 -1
  54. package/types/c8y-ngx-components-echart.d.ts +12 -0
  55. package/types/c8y-ngx-components-echart.d.ts.map +1 -1
  56. package/types/c8y-ngx-components-time-context.d.ts +2 -0
  57. package/types/c8y-ngx-components-time-context.d.ts.map +1 -1
  58. package/types/c8y-ngx-components-widgets-implementations-scada.d.ts.map +1 -1
  59. package/types/c8y-ngx-components.d.ts +10 -1
  60. package/types/c8y-ngx-components.d.ts.map +1 -1
@@ -179,9 +179,8 @@ class TimeContextComponent {
179
179
  aggregation: incomingAutoAggregation ? null : this.changedDateContext.aggregation,
180
180
  autoAggregation: incomingAutoAggregation
181
181
  }, false);
182
- if (this.changedDateContext.realtime) {
183
- this.form.controls.aggregation.disable();
184
- }
182
+ // Silent like the update() above: parent-driven changes must not emit back.
183
+ this.setRealtimeControlsLocked(!!this.changedDateContext.realtime, { emitEvent: false });
185
184
  }
186
185
  }
187
186
  /** Called by the aggregation picker's (autoModeChange) output. */
@@ -213,14 +212,21 @@ class TimeContextComponent {
213
212
  }
214
213
  stopRealtime() {
215
214
  this.realtimeSubscription?.unsubscribe();
216
- this.form?.controls.temporaryUserSelectedFromDate.enable();
217
- this.form?.controls.temporaryUserSelectedToDate.enable();
218
- this.form?.controls.aggregation.enable();
215
+ this.setRealtimeControlsLocked(false);
219
216
  // Update the form value without triggering valueChanges to avoid infinite loop
220
217
  if (this.form?.value.realtime) {
221
218
  this.form.patchValue({ realtime: false }, { emitEvent: false });
222
219
  }
223
220
  }
221
+ /** Realtime locks manual range selection and aggregation; single owner of that control set. */
222
+ setRealtimeControlsLocked(locked, options) {
223
+ const controls = [
224
+ this.form.controls.temporaryUserSelectedFromDate,
225
+ this.form.controls.temporaryUserSelectedToDate,
226
+ this.form.controls.aggregation
227
+ ];
228
+ controls.forEach(control => (locked ? control.disable(options) : control.enable(options)));
229
+ }
224
230
  subscribeToIntervalChange() {
225
231
  this.form.controls.currentDateContextInterval.valueChanges
226
232
  .pipe(takeUntilDestroyed(this.#destroyRef))
@@ -367,9 +373,7 @@ class TimeContextComponent {
367
373
  });
368
374
  }
369
375
  startRealtime() {
370
- this.form.controls.temporaryUserSelectedFromDate.disable();
371
- this.form.controls.temporaryUserSelectedToDate.disable();
372
- this.form.controls.aggregation.disable();
376
+ this.setRealtimeControlsLocked(true);
373
377
  this.realtimeSubscription = interval(this.REALTIME_INTERVAL)
374
378
  .pipe(takeUntilDestroyed(this.#destroyRef))
375
379
  .subscribe(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-time-context.mjs","sources":["../../time-context/time-context.service.ts","../../time-context/time-context.component.ts","../../time-context/time-context.component.html","../../time-context/c8y-ngx-components-time-context.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { aggregationType } from '@c8y/client';\nimport { AGGREGATION_LIMITS, DateTimeContext } from '@c8y/ngx-components';\nimport { Interval, INTERVALS, TimeSpanInMs } from '@c8y/ngx-components/interval-picker';\nimport { TimeContext } from './time-context.model';\n\ninterface TimeRangeValidation {\n aggregationType: aggregationType;\n isDisabled: boolean;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class DatapointExplorerService {\n readonly DEFAULT_INTERVAL: Interval['id'] = 'days';\n\n // Create generic? Based on packages/ngx-components/core/dashboard/wiget-time-context/widget-time-context.component.html\n getDefaultContext(overrides?: Partial<TimeContext>): TimeContext {\n return {\n date: this.getDateTimeContextByInterval(overrides?.interval ?? this.DEFAULT_INTERVAL),\n interval: this.DEFAULT_INTERVAL,\n realtime: false,\n aggregation: aggregationType.MINUTELY,\n ...overrides\n };\n }\n\n calculateAggregation(\n [dateFrom, dateTo]: DateTimeContext,\n requestedAggregation: aggregationType | null\n ): {\n selectedAggregation: aggregationType | null;\n disabledAggregations: Partial<Record<aggregationType, boolean>>;\n } {\n const timeRangeValidations = this.validateTimeRanges([dateFrom, dateTo]);\n const disabledAggregations = this.getDisabledAggregations(timeRangeValidations);\n\n const timeRangeInMs = this.getTimeRangeInMs(dateFrom, dateTo);\n\n const isRequestedAggregationValid =\n requestedAggregation === null || !disabledAggregations[requestedAggregation];\n\n const selectedAggregation = isRequestedAggregationValid\n ? requestedAggregation\n : this.determineAggregation(timeRangeInMs);\n\n return {\n selectedAggregation,\n disabledAggregations\n };\n }\n\n getDateTimeContextByInterval(intervalId: Interval['id']): DateTimeContext {\n const interval = INTERVALS.find(({ id }) => id === intervalId);\n const dateTo = new Date();\n const dateFrom = new Date(dateTo.valueOf() - interval.timespanInMs);\n return [dateFrom, dateTo];\n }\n\n private getTimeRangeInMs(dateFrom: Date, dateTo: Date): number {\n return dateTo.valueOf() - dateFrom.valueOf();\n }\n\n private validateTimeRanges([dateFrom, dateTo]: DateTimeContext): TimeRangeValidation[] {\n const timeRangeInMs = this.getTimeRangeInMs(dateFrom, dateTo);\n\n return [\n {\n aggregationType: aggregationType.DAILY,\n isDisabled: timeRangeInMs <= TimeSpanInMs.DAY\n },\n {\n aggregationType: aggregationType.HOURLY,\n isDisabled: timeRangeInMs <= TimeSpanInMs.HOUR\n },\n {\n aggregationType: aggregationType.MINUTELY,\n isDisabled: timeRangeInMs <= TimeSpanInMs.MINUTE\n }\n ];\n }\n\n private getDisabledAggregations(\n timeRangeValidations: TimeRangeValidation[]\n ): Partial<Record<aggregationType, boolean>> {\n return timeRangeValidations.reduce(\n (acc, { aggregationType, isDisabled }) => ({\n ...acc,\n [aggregationType]: isDisabled\n }),\n {}\n );\n }\n\n private determineAggregation(timeRangeInMs: number): aggregationType | null {\n if (timeRangeInMs >= AGGREGATION_LIMITS.DAILY_LIMIT) {\n return aggregationType.DAILY;\n } else if (timeRangeInMs >= AGGREGATION_LIMITS.HOURLY_LIMIT) {\n return aggregationType.HOURLY;\n } else if (timeRangeInMs >= AGGREGATION_LIMITS.MINUTELY_LIMIT) {\n return aggregationType.MINUTELY;\n }\n return null;\n }\n}\n","import {\n Component,\n DestroyRef,\n inject,\n Input,\n model,\n OnInit,\n signal,\n SimpleChanges,\n ViewChild\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { FormBuilder } from '@angular/forms';\nimport {\n AggregationPickerComponent,\n CoreModule,\n DateAndTimeOptions,\n DateTimeContext,\n DateTimePickerModule,\n WidgetTimeContextDateRangeService\n} from '@c8y/ngx-components';\nimport {\n AGGREGATION_POPOVER_TEXT,\n AUTO_AGGREGATION_DATAPOINTS,\n AutoAggregationConfig,\n RealtimeControlComponent,\n TimeSeriesMigrationService,\n TIMING\n} from '@c8y/ngx-components/global-context';\nimport {\n Interval,\n INTERVAL_TITLES,\n IntervalPickerComponent\n} from '@c8y/ngx-components/interval-picker';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { BsDatepickerModule } from 'ngx-bootstrap/datepicker';\nimport { BsDropdownDirective, BsDropdownModule } from 'ngx-bootstrap/dropdown';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport { PopoverModule } from 'ngx-bootstrap/popover';\nimport { debounceTime, interval, Subscription } from 'rxjs';\nimport { TimeContext } from './time-context.model';\nimport { DatapointExplorerService } from './time-context.service';\n\n// TODO: REMOVE THIS FILE\n@Component({\n selector: 'c8y-time-context',\n templateUrl: './time-context.component.html',\n standalone: true,\n imports: [\n CoreModule,\n BsDatepickerModule,\n DateTimePickerModule,\n BsDropdownModule,\n AggregationPickerComponent,\n TooltipModule,\n PopoverModule,\n IntervalPickerComponent,\n RealtimeControlComponent\n ]\n})\nexport class TimeContextComponent implements OnInit {\n @Input() changedDateContext: {\n dateFrom?: Date;\n dateTo?: Date;\n interval?: Interval['id'];\n realtime?: boolean;\n aggregation?: string;\n autoAggregation?: AutoAggregationConfig | null;\n };\n @Input() controlsAvailable: any;\n @Input() timeContext: Partial<TimeContext> = {};\n @Input() timePickerConfig: DateAndTimeOptions = {\n showMinutes: true,\n showSeconds: false,\n showSpinners: false\n };\n @Input() enableAutoAggregation = false;\n @ViewChild(BsDropdownDirective) dropdown: BsDropdownDirective;\n datapointExplorerService = inject(DatapointExplorerService);\n formBuilder = inject(FormBuilder);\n #destroyRef = inject(DestroyRef);\n #timeSeriesMigrationService = inject(TimeSeriesMigrationService);\n\n readonly DATE_FORMAT = 'short';\n readonly INTERVAL_TITLES = INTERVAL_TITLES;\n readonly REALTIME_INTERVAL = 1000;\n readonly AUTO_AGGREGATION_DATAPOINTS = AUTO_AGGREGATION_DATAPOINTS;\n readonly AGGREGATION_POPOVER = AGGREGATION_POPOVER_TEXT;\n readonly KEEP_DATA_ON_ZOOM_IN_POPOVER = gettext(\n '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.'\n );\n /** Whether auto-aggregation mode is active. */\n readonly isAutoModeActive = signal(false);\n /**\n * The \"Auto\" aggregation option requires the tenant to be migrated to time series\n * (auto mode uses `aggregationInterval`, unsupported on non-migrated tenants).\n */\n readonly isTimeSeriesMigrated = signal(false);\n form = this.createForm(this.datapointExplorerService.getDefaultContext());\n disabledAggregations;\n\n /** Last datapoints value applied to the context; restored when the field is left empty. */\n private lastAppliedDatapoints: number = AUTO_AGGREGATION_DATAPOINTS.DEFAULT;\n\n readonly valuesSignal = toSignal(this.form.controls.currentDateContextFromDate.valueChanges, {\n initialValue: this.form.controls.currentDateContextFromDate.value\n });\n\n context = model(this.form.value);\n\n private realtimeSubscription: Subscription;\n\n constructor(private widgetTimeContextDateRangeService: WidgetTimeContextDateRangeService) {}\n\n ngOnInit(): void {\n this.form.patchValue(this.datapointExplorerService.getDefaultContext(this.timeContext));\n const context = this.datapointExplorerService.getDefaultContext(this.timeContext);\n const { disabledAggregations } = this.datapointExplorerService.calculateAggregation(\n context.date,\n context.aggregation\n );\n this.disabledAggregations = disabledAggregations;\n\n this.#timeSeriesMigrationService\n .isTimeSeriesMigrated()\n .then(isMigrated => this.isTimeSeriesMigrated.set(isMigrated));\n\n this.subscribeToIntervalChange();\n this.subscribeToRealtimeChange();\n this.subscribeToAggregationChange();\n this.subscribeToDatapointsChange();\n this.subscribeToKeepDataOnZoomInChange();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes.changedDateContext && changes.changedDateContext.currentValue) {\n // In realtime mode, ignore updates from parent - the component updates itself via interval\n if (this.changedDateContext.realtime && this.form.value.realtime) {\n return;\n }\n\n // Check if values actually changed (not just object reference)\n const currentFormValues = this.form.value;\n const newDateFrom = this.changedDateContext.dateFrom?.toISOString();\n const newDateTo = this.changedDateContext.dateTo?.toISOString();\n\n const hasActualChanges =\n newDateFrom !== currentFormValues.currentDateContextFromDate ||\n newDateTo !== currentFormValues.currentDateContextToDate ||\n this.changedDateContext.interval !== currentFormValues.currentDateContextInterval ||\n this.changedDateContext.realtime !== currentFormValues.realtime ||\n this.changedDateContext.aggregation !== currentFormValues.aggregation ||\n !!this.changedDateContext.autoAggregation !== currentFormValues.autoAggregationEnabled;\n\n if (!hasActualChanges) {\n return;\n }\n\n // Don't emit when update comes from parent (avoid infinite loop)\n const incomingAutoAggregation = this.changedDateContext.autoAggregation ?? null;\n this.isAutoModeActive.set(!!incomingAutoAggregation);\n this.update(\n {\n date: [this.changedDateContext.dateFrom, this.changedDateContext.dateTo],\n interval: this.changedDateContext.interval,\n realtime: this.changedDateContext.realtime || false,\n aggregation: incomingAutoAggregation ? null : this.changedDateContext.aggregation,\n autoAggregation: incomingAutoAggregation\n },\n false\n );\n if (this.changedDateContext.realtime) {\n this.form.controls.aggregation.disable();\n }\n }\n }\n\n /** Called by the aggregation picker's (autoModeChange) output. */\n onAutoModeChange(isAuto: boolean): void {\n this.isAutoModeActive.set(isAuto);\n this.update({\n date: [\n new Date(this.form.value.currentDateContextFromDate),\n new Date(this.form.value.currentDateContextToDate)\n ],\n interval: this.form.value.currentDateContextInterval,\n realtime: this.form.value.realtime,\n aggregation: isAuto ? null : this.form.value.aggregation,\n autoAggregation: isAuto ? this.buildAutoAggregationConfig() : null\n });\n }\n\n applyDatetimeContext(): void {\n const isAuto = this.isAutoModeActive();\n this.update({\n date: [\n new Date(this.form.controls.temporaryUserSelectedFromDate.value),\n new Date(this.form.controls.temporaryUserSelectedToDate.value)\n ],\n interval: 'custom',\n realtime: this.form.value.realtime,\n aggregation: isAuto ? null : this.form.value.aggregation,\n autoAggregation: isAuto ? this.buildAutoAggregationConfig() : null\n });\n }\n\n stopRealtime(): void {\n this.realtimeSubscription?.unsubscribe();\n this.form?.controls.temporaryUserSelectedFromDate.enable();\n this.form?.controls.temporaryUserSelectedToDate.enable();\n this.form?.controls.aggregation.enable();\n // Update the form value without triggering valueChanges to avoid infinite loop\n if (this.form?.value.realtime) {\n this.form.patchValue({ realtime: false }, { emitEvent: false });\n }\n }\n\n private subscribeToIntervalChange(): void {\n this.form.controls.currentDateContextInterval.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(interval => {\n let date: DateTimeContext;\n // Only reset initialTimeRange for preset intervals, not 'custom'\n // Custom interval is set by user slider interaction, which shouldn't reset the chart\n if (interval !== 'custom') {\n this.widgetTimeContextDateRangeService.updateInitialTimeRange(null);\n }\n if (interval === 'custom') {\n date = [\n new Date(this.form.controls.currentDateContextFromDate.value),\n new Date(this.form.controls.currentDateContextToDate.value)\n ];\n } else {\n date = this.datapointExplorerService.getDateTimeContextByInterval(\n interval as Interval['id']\n );\n this.dropdown.isOpen = false;\n }\n this.update({\n date,\n interval,\n realtime: this.form.value.realtime,\n aggregation: this.isAutoModeActive() ? null : this.form.value.aggregation,\n autoAggregation: this.isAutoModeActive() ? this.buildAutoAggregationConfig() : null\n });\n });\n }\n\n private subscribeToRealtimeChange(): void {\n this.form.controls.realtime.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(realtime => {\n this.onRealtimeValueChange(realtime as boolean);\n\n if (realtime) {\n this.startRealtime();\n } else {\n this.stopRealtime();\n }\n });\n }\n\n private subscribeToAggregationChange() {\n this.form.controls.aggregation.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(aggregation => {\n // Skip during auto mode transitions — onAutoModeChange handles the update\n if (this.isAutoModeActive()) {\n return;\n }\n this.update({\n date: [\n new Date(this.form.value.currentDateContextFromDate),\n new Date(this.form.value.currentDateContextToDate)\n ],\n interval: this.form.value.currentDateContextInterval,\n realtime: this.form.value.realtime,\n aggregation,\n autoAggregation: null\n });\n });\n }\n\n private subscribeToDatapointsChange(): void {\n this.form.controls.autoAggregationDatapoints.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef), debounceTime(TIMING.TYPING_DEBOUNCE))\n .subscribe(datapoints => {\n if (!this.isAutoModeActive()) {\n return;\n }\n // Skip while the field is empty or out of range — the user is still typing. Rewriting\n // or emitting a clamped value here would snap the field back mid-edit;\n // commitDatapoints() (blur) commits a valid value instead.\n if (!this.isValidDatapoints(datapoints)) {\n return;\n }\n this.emitAutoAggregationUpdate();\n });\n }\n\n private isValidDatapoints(value: number | null | undefined): value is number {\n return (\n typeof value === 'number' &&\n !Number.isNaN(value) &&\n value >= AUTO_AGGREGATION_DATAPOINTS.MIN &&\n value <= AUTO_AGGREGATION_DATAPOINTS.MAX\n );\n }\n\n private clampToDatapointsBounds(value: number): number {\n return Math.min(\n AUTO_AGGREGATION_DATAPOINTS.MAX,\n Math.max(AUTO_AGGREGATION_DATAPOINTS.MIN, value)\n );\n }\n\n private subscribeToKeepDataOnZoomInChange(): void {\n this.form.controls.autoAggregationKeepDataOnZoomIn.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(() => {\n if (!this.isAutoModeActive()) {\n return;\n }\n this.emitAutoAggregationUpdate();\n });\n }\n\n private emitAutoAggregationUpdate(): void {\n this.update({\n date: [\n new Date(this.form.value.currentDateContextFromDate),\n new Date(this.form.value.currentDateContextToDate)\n ],\n interval: this.form.value.currentDateContextInterval,\n realtime: this.form.value.realtime,\n aggregation: null,\n autoAggregation: this.buildAutoAggregationConfig()\n });\n }\n\n /**\n * Builds the auto-aggregation config from the current form state, clamped to the allowed\n * range. Falls back to the last applied value while the field is empty (mid-edit).\n *\n * Reads control values instead of `this.form.value`: a control's valueChanges fires before\n * the parent group recomputes its cached value, so the group value is stale inside the\n * subscriptions that call this method.\n */\n private buildAutoAggregationConfig(): AutoAggregationConfig {\n const datapoints = this.clampToDatapointsBounds(\n this.form.controls.autoAggregationDatapoints.value ?? this.lastAppliedDatapoints\n );\n return {\n datapoints,\n keepDataOnZoomIn: this.form.controls.autoAggregationKeepDataOnZoomIn.value ?? true\n };\n }\n\n private onRealtimeValueChange(realtime: boolean): void {\n let dateTimeContext: DateTimeContext;\n if (this.form.value.currentDateContextInterval !== 'custom') {\n dateTimeContext = this.datapointExplorerService.getDateTimeContextByInterval(\n this.form.value.currentDateContextInterval as Interval['id']\n );\n } else {\n const currentTimeSpanInMs =\n new Date(this.form.value.currentDateContextToDate).valueOf() -\n new Date(this.form.value.currentDateContextFromDate).valueOf();\n const dateTo = new Date();\n const dateFrom = new Date(dateTo.valueOf() - currentTimeSpanInMs);\n dateTimeContext = [dateFrom, dateTo];\n }\n\n this.isAutoModeActive.set(false);\n this.update({\n date: dateTimeContext,\n interval: this.form.value.currentDateContextInterval,\n realtime,\n aggregation: null,\n autoAggregation: null\n });\n }\n\n private startRealtime(): void {\n this.form.controls.temporaryUserSelectedFromDate.disable();\n this.form.controls.temporaryUserSelectedToDate.disable();\n this.form.controls.aggregation.disable();\n\n this.realtimeSubscription = interval(this.REALTIME_INTERVAL)\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(() => {\n if (!this.form.value.realtime) {\n this.realtimeSubscription.unsubscribe();\n return;\n }\n const newDateFrom = new Date(\n new Date(this.form.value.currentDateContextFromDate).valueOf() + this.REALTIME_INTERVAL\n );\n const newDateTo = new Date(\n new Date(this.form.value.currentDateContextToDate).valueOf() + this.REALTIME_INTERVAL\n );\n this.updateFormValues(\n {\n date: [newDateFrom, newDateTo],\n interval: this.form.value.currentDateContextInterval,\n realtime: true,\n aggregation: null\n },\n false\n ); // Don't emit during automatic realtime ticks\n });\n }\n\n private update(\n { date, interval, realtime, aggregation, autoAggregation = null },\n shouldEmit = true\n ): void {\n const { selectedAggregation, disabledAggregations } =\n this.datapointExplorerService.calculateAggregation(\n date,\n autoAggregation ? null : aggregation\n );\n this.disabledAggregations = disabledAggregations;\n this.updateFormValues(\n { date, interval, realtime, aggregation: selectedAggregation, autoAggregation },\n shouldEmit\n );\n }\n\n private createForm(context) {\n return this.formBuilder.group({\n temporaryUserSelectedFromDate: context.date[0].toISOString() as string,\n temporaryUserSelectedToDate: context.date[1].toISOString() as string,\n currentDateContextFromDate: context.date[0].toISOString() as string,\n currentDateContextToDate: context.date[1].toISOString() as string,\n currentDateContextInterval: context.interval || 'custom',\n realtime: context.realtime,\n aggregation: context.aggregation,\n autoAggregationEnabled: false,\n autoAggregationDatapoints: AUTO_AGGREGATION_DATAPOINTS.DEFAULT as number,\n autoAggregationKeepDataOnZoomIn: true\n });\n }\n\n private updateFormValues(\n { date, interval, realtime, aggregation, autoAggregation = null },\n shouldEmit = true\n ): void {\n const newFormValues = {\n temporaryUserSelectedFromDate: date[0].toISOString() as string,\n temporaryUserSelectedToDate: date[1].toISOString() as string,\n currentDateContextFromDate: date[0].toISOString() as string,\n currentDateContextToDate: date[1].toISOString() as string,\n realtime,\n currentDateContextInterval: interval || 'custom',\n aggregation: autoAggregation ? null : aggregation || null,\n autoAggregation\n };\n\n if (shouldEmit) {\n this.context.set(newFormValues);\n }\n if (autoAggregation?.datapoints != null) {\n this.lastAppliedDatapoints = this.clampToDatapointsBounds(autoAggregation.datapoints);\n }\n this.form.patchValue(\n {\n ...newFormValues,\n autoAggregationEnabled: !!autoAggregation,\n autoAggregationDatapoints:\n autoAggregation?.datapoints ?? this.form.value.autoAggregationDatapoints,\n autoAggregationKeepDataOnZoomIn:\n autoAggregation?.keepDataOnZoomIn ?? this.form.value.autoAggregationKeepDataOnZoomIn\n },\n { emitEvent: false }\n );\n }\n}\n","@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 }} — {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} — {{ 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 }} — {{ 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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-time-context.mjs","sources":["../../time-context/time-context.service.ts","../../time-context/time-context.component.ts","../../time-context/time-context.component.html","../../time-context/c8y-ngx-components-time-context.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { aggregationType } from '@c8y/client';\nimport { AGGREGATION_LIMITS, DateTimeContext } from '@c8y/ngx-components';\nimport { Interval, INTERVALS, TimeSpanInMs } from '@c8y/ngx-components/interval-picker';\nimport { TimeContext } from './time-context.model';\n\ninterface TimeRangeValidation {\n aggregationType: aggregationType;\n isDisabled: boolean;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class DatapointExplorerService {\n readonly DEFAULT_INTERVAL: Interval['id'] = 'days';\n\n // Create generic? Based on packages/ngx-components/core/dashboard/wiget-time-context/widget-time-context.component.html\n getDefaultContext(overrides?: Partial<TimeContext>): TimeContext {\n return {\n date: this.getDateTimeContextByInterval(overrides?.interval ?? this.DEFAULT_INTERVAL),\n interval: this.DEFAULT_INTERVAL,\n realtime: false,\n aggregation: aggregationType.MINUTELY,\n ...overrides\n };\n }\n\n calculateAggregation(\n [dateFrom, dateTo]: DateTimeContext,\n requestedAggregation: aggregationType | null\n ): {\n selectedAggregation: aggregationType | null;\n disabledAggregations: Partial<Record<aggregationType, boolean>>;\n } {\n const timeRangeValidations = this.validateTimeRanges([dateFrom, dateTo]);\n const disabledAggregations = this.getDisabledAggregations(timeRangeValidations);\n\n const timeRangeInMs = this.getTimeRangeInMs(dateFrom, dateTo);\n\n const isRequestedAggregationValid =\n requestedAggregation === null || !disabledAggregations[requestedAggregation];\n\n const selectedAggregation = isRequestedAggregationValid\n ? requestedAggregation\n : this.determineAggregation(timeRangeInMs);\n\n return {\n selectedAggregation,\n disabledAggregations\n };\n }\n\n getDateTimeContextByInterval(intervalId: Interval['id']): DateTimeContext {\n const interval = INTERVALS.find(({ id }) => id === intervalId);\n const dateTo = new Date();\n const dateFrom = new Date(dateTo.valueOf() - interval.timespanInMs);\n return [dateFrom, dateTo];\n }\n\n private getTimeRangeInMs(dateFrom: Date, dateTo: Date): number {\n return dateTo.valueOf() - dateFrom.valueOf();\n }\n\n private validateTimeRanges([dateFrom, dateTo]: DateTimeContext): TimeRangeValidation[] {\n const timeRangeInMs = this.getTimeRangeInMs(dateFrom, dateTo);\n\n return [\n {\n aggregationType: aggregationType.DAILY,\n isDisabled: timeRangeInMs <= TimeSpanInMs.DAY\n },\n {\n aggregationType: aggregationType.HOURLY,\n isDisabled: timeRangeInMs <= TimeSpanInMs.HOUR\n },\n {\n aggregationType: aggregationType.MINUTELY,\n isDisabled: timeRangeInMs <= TimeSpanInMs.MINUTE\n }\n ];\n }\n\n private getDisabledAggregations(\n timeRangeValidations: TimeRangeValidation[]\n ): Partial<Record<aggregationType, boolean>> {\n return timeRangeValidations.reduce(\n (acc, { aggregationType, isDisabled }) => ({\n ...acc,\n [aggregationType]: isDisabled\n }),\n {}\n );\n }\n\n private determineAggregation(timeRangeInMs: number): aggregationType | null {\n if (timeRangeInMs >= AGGREGATION_LIMITS.DAILY_LIMIT) {\n return aggregationType.DAILY;\n } else if (timeRangeInMs >= AGGREGATION_LIMITS.HOURLY_LIMIT) {\n return aggregationType.HOURLY;\n } else if (timeRangeInMs >= AGGREGATION_LIMITS.MINUTELY_LIMIT) {\n return aggregationType.MINUTELY;\n }\n return null;\n }\n}\n","import {\n Component,\n DestroyRef,\n inject,\n Input,\n model,\n OnInit,\n signal,\n SimpleChanges,\n ViewChild\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { FormBuilder } from '@angular/forms';\nimport {\n AggregationPickerComponent,\n CoreModule,\n DateAndTimeOptions,\n DateTimeContext,\n DateTimePickerModule,\n WidgetTimeContextDateRangeService\n} from '@c8y/ngx-components';\nimport {\n AGGREGATION_POPOVER_TEXT,\n AUTO_AGGREGATION_DATAPOINTS,\n AutoAggregationConfig,\n RealtimeControlComponent,\n TimeSeriesMigrationService,\n TIMING\n} from '@c8y/ngx-components/global-context';\nimport {\n Interval,\n INTERVAL_TITLES,\n IntervalPickerComponent\n} from '@c8y/ngx-components/interval-picker';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { BsDatepickerModule } from 'ngx-bootstrap/datepicker';\nimport { BsDropdownDirective, BsDropdownModule } from 'ngx-bootstrap/dropdown';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport { PopoverModule } from 'ngx-bootstrap/popover';\nimport { debounceTime, interval, Subscription } from 'rxjs';\nimport { TimeContext } from './time-context.model';\nimport { DatapointExplorerService } from './time-context.service';\n\n// TODO: REMOVE THIS FILE\n@Component({\n selector: 'c8y-time-context',\n templateUrl: './time-context.component.html',\n standalone: true,\n imports: [\n CoreModule,\n BsDatepickerModule,\n DateTimePickerModule,\n BsDropdownModule,\n AggregationPickerComponent,\n TooltipModule,\n PopoverModule,\n IntervalPickerComponent,\n RealtimeControlComponent\n ]\n})\nexport class TimeContextComponent implements OnInit {\n @Input() changedDateContext: {\n dateFrom?: Date;\n dateTo?: Date;\n interval?: Interval['id'];\n realtime?: boolean;\n aggregation?: string;\n autoAggregation?: AutoAggregationConfig | null;\n };\n @Input() controlsAvailable: any;\n @Input() timeContext: Partial<TimeContext> = {};\n @Input() timePickerConfig: DateAndTimeOptions = {\n showMinutes: true,\n showSeconds: false,\n showSpinners: false\n };\n @Input() enableAutoAggregation = false;\n @ViewChild(BsDropdownDirective) dropdown: BsDropdownDirective;\n datapointExplorerService = inject(DatapointExplorerService);\n formBuilder = inject(FormBuilder);\n #destroyRef = inject(DestroyRef);\n #timeSeriesMigrationService = inject(TimeSeriesMigrationService);\n\n readonly DATE_FORMAT = 'short';\n readonly INTERVAL_TITLES = INTERVAL_TITLES;\n readonly REALTIME_INTERVAL = 1000;\n readonly AUTO_AGGREGATION_DATAPOINTS = AUTO_AGGREGATION_DATAPOINTS;\n readonly AGGREGATION_POPOVER = AGGREGATION_POPOVER_TEXT;\n readonly KEEP_DATA_ON_ZOOM_IN_POPOVER = gettext(\n '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.'\n );\n /** Whether auto-aggregation mode is active. */\n readonly isAutoModeActive = signal(false);\n /**\n * The \"Auto\" aggregation option requires the tenant to be migrated to time series\n * (auto mode uses `aggregationInterval`, unsupported on non-migrated tenants).\n */\n readonly isTimeSeriesMigrated = signal(false);\n form = this.createForm(this.datapointExplorerService.getDefaultContext());\n disabledAggregations;\n\n /** Last datapoints value applied to the context; restored when the field is left empty. */\n private lastAppliedDatapoints: number = AUTO_AGGREGATION_DATAPOINTS.DEFAULT;\n\n readonly valuesSignal = toSignal(this.form.controls.currentDateContextFromDate.valueChanges, {\n initialValue: this.form.controls.currentDateContextFromDate.value\n });\n\n context = model(this.form.value);\n\n private realtimeSubscription: Subscription;\n\n constructor(private widgetTimeContextDateRangeService: WidgetTimeContextDateRangeService) {}\n\n ngOnInit(): void {\n this.form.patchValue(this.datapointExplorerService.getDefaultContext(this.timeContext));\n const context = this.datapointExplorerService.getDefaultContext(this.timeContext);\n const { disabledAggregations } = this.datapointExplorerService.calculateAggregation(\n context.date,\n context.aggregation\n );\n this.disabledAggregations = disabledAggregations;\n\n this.#timeSeriesMigrationService\n .isTimeSeriesMigrated()\n .then(isMigrated => this.isTimeSeriesMigrated.set(isMigrated));\n\n this.subscribeToIntervalChange();\n this.subscribeToRealtimeChange();\n this.subscribeToAggregationChange();\n this.subscribeToDatapointsChange();\n this.subscribeToKeepDataOnZoomInChange();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes.changedDateContext && changes.changedDateContext.currentValue) {\n // In realtime mode, ignore updates from parent - the component updates itself via interval\n if (this.changedDateContext.realtime && this.form.value.realtime) {\n return;\n }\n\n // Check if values actually changed (not just object reference)\n const currentFormValues = this.form.value;\n const newDateFrom = this.changedDateContext.dateFrom?.toISOString();\n const newDateTo = this.changedDateContext.dateTo?.toISOString();\n\n const hasActualChanges =\n newDateFrom !== currentFormValues.currentDateContextFromDate ||\n newDateTo !== currentFormValues.currentDateContextToDate ||\n this.changedDateContext.interval !== currentFormValues.currentDateContextInterval ||\n this.changedDateContext.realtime !== currentFormValues.realtime ||\n this.changedDateContext.aggregation !== currentFormValues.aggregation ||\n !!this.changedDateContext.autoAggregation !== currentFormValues.autoAggregationEnabled;\n\n if (!hasActualChanges) {\n return;\n }\n\n // Don't emit when update comes from parent (avoid infinite loop)\n const incomingAutoAggregation = this.changedDateContext.autoAggregation ?? null;\n this.isAutoModeActive.set(!!incomingAutoAggregation);\n this.update(\n {\n date: [this.changedDateContext.dateFrom, this.changedDateContext.dateTo],\n interval: this.changedDateContext.interval,\n realtime: this.changedDateContext.realtime || false,\n aggregation: incomingAutoAggregation ? null : this.changedDateContext.aggregation,\n autoAggregation: incomingAutoAggregation\n },\n false\n );\n // Silent like the update() above: parent-driven changes must not emit back.\n this.setRealtimeControlsLocked(!!this.changedDateContext.realtime, { emitEvent: false });\n }\n }\n\n /** Called by the aggregation picker's (autoModeChange) output. */\n onAutoModeChange(isAuto: boolean): void {\n this.isAutoModeActive.set(isAuto);\n this.update({\n date: [\n new Date(this.form.value.currentDateContextFromDate),\n new Date(this.form.value.currentDateContextToDate)\n ],\n interval: this.form.value.currentDateContextInterval,\n realtime: this.form.value.realtime,\n aggregation: isAuto ? null : this.form.value.aggregation,\n autoAggregation: isAuto ? this.buildAutoAggregationConfig() : null\n });\n }\n\n applyDatetimeContext(): void {\n const isAuto = this.isAutoModeActive();\n this.update({\n date: [\n new Date(this.form.controls.temporaryUserSelectedFromDate.value),\n new Date(this.form.controls.temporaryUserSelectedToDate.value)\n ],\n interval: 'custom',\n realtime: this.form.value.realtime,\n aggregation: isAuto ? null : this.form.value.aggregation,\n autoAggregation: isAuto ? this.buildAutoAggregationConfig() : null\n });\n }\n\n stopRealtime(): void {\n this.realtimeSubscription?.unsubscribe();\n this.setRealtimeControlsLocked(false);\n // Update the form value without triggering valueChanges to avoid infinite loop\n if (this.form?.value.realtime) {\n this.form.patchValue({ realtime: false }, { emitEvent: false });\n }\n }\n\n /** Realtime locks manual range selection and aggregation; single owner of that control set. */\n private setRealtimeControlsLocked(locked: boolean, options?: { emitEvent: boolean }): void {\n const controls = [\n this.form.controls.temporaryUserSelectedFromDate,\n this.form.controls.temporaryUserSelectedToDate,\n this.form.controls.aggregation\n ];\n controls.forEach(control => (locked ? control.disable(options) : control.enable(options)));\n }\n\n private subscribeToIntervalChange(): void {\n this.form.controls.currentDateContextInterval.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(interval => {\n let date: DateTimeContext;\n // Only reset initialTimeRange for preset intervals, not 'custom'\n // Custom interval is set by user slider interaction, which shouldn't reset the chart\n if (interval !== 'custom') {\n this.widgetTimeContextDateRangeService.updateInitialTimeRange(null);\n }\n if (interval === 'custom') {\n date = [\n new Date(this.form.controls.currentDateContextFromDate.value),\n new Date(this.form.controls.currentDateContextToDate.value)\n ];\n } else {\n date = this.datapointExplorerService.getDateTimeContextByInterval(\n interval as Interval['id']\n );\n this.dropdown.isOpen = false;\n }\n this.update({\n date,\n interval,\n realtime: this.form.value.realtime,\n aggregation: this.isAutoModeActive() ? null : this.form.value.aggregation,\n autoAggregation: this.isAutoModeActive() ? this.buildAutoAggregationConfig() : null\n });\n });\n }\n\n private subscribeToRealtimeChange(): void {\n this.form.controls.realtime.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(realtime => {\n this.onRealtimeValueChange(realtime as boolean);\n\n if (realtime) {\n this.startRealtime();\n } else {\n this.stopRealtime();\n }\n });\n }\n\n private subscribeToAggregationChange() {\n this.form.controls.aggregation.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(aggregation => {\n // Skip during auto mode transitions — onAutoModeChange handles the update\n if (this.isAutoModeActive()) {\n return;\n }\n this.update({\n date: [\n new Date(this.form.value.currentDateContextFromDate),\n new Date(this.form.value.currentDateContextToDate)\n ],\n interval: this.form.value.currentDateContextInterval,\n realtime: this.form.value.realtime,\n aggregation,\n autoAggregation: null\n });\n });\n }\n\n private subscribeToDatapointsChange(): void {\n this.form.controls.autoAggregationDatapoints.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef), debounceTime(TIMING.TYPING_DEBOUNCE))\n .subscribe(datapoints => {\n if (!this.isAutoModeActive()) {\n return;\n }\n // Skip while the field is empty or out of range — the user is still typing. Rewriting\n // or emitting a clamped value here would snap the field back mid-edit;\n // commitDatapoints() (blur) commits a valid value instead.\n if (!this.isValidDatapoints(datapoints)) {\n return;\n }\n this.emitAutoAggregationUpdate();\n });\n }\n\n private isValidDatapoints(value: number | null | undefined): value is number {\n return (\n typeof value === 'number' &&\n !Number.isNaN(value) &&\n value >= AUTO_AGGREGATION_DATAPOINTS.MIN &&\n value <= AUTO_AGGREGATION_DATAPOINTS.MAX\n );\n }\n\n private clampToDatapointsBounds(value: number): number {\n return Math.min(\n AUTO_AGGREGATION_DATAPOINTS.MAX,\n Math.max(AUTO_AGGREGATION_DATAPOINTS.MIN, value)\n );\n }\n\n private subscribeToKeepDataOnZoomInChange(): void {\n this.form.controls.autoAggregationKeepDataOnZoomIn.valueChanges\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(() => {\n if (!this.isAutoModeActive()) {\n return;\n }\n this.emitAutoAggregationUpdate();\n });\n }\n\n private emitAutoAggregationUpdate(): void {\n this.update({\n date: [\n new Date(this.form.value.currentDateContextFromDate),\n new Date(this.form.value.currentDateContextToDate)\n ],\n interval: this.form.value.currentDateContextInterval,\n realtime: this.form.value.realtime,\n aggregation: null,\n autoAggregation: this.buildAutoAggregationConfig()\n });\n }\n\n /**\n * Builds the auto-aggregation config from the current form state, clamped to the allowed\n * range. Falls back to the last applied value while the field is empty (mid-edit).\n *\n * Reads control values instead of `this.form.value`: a control's valueChanges fires before\n * the parent group recomputes its cached value, so the group value is stale inside the\n * subscriptions that call this method.\n */\n private buildAutoAggregationConfig(): AutoAggregationConfig {\n const datapoints = this.clampToDatapointsBounds(\n this.form.controls.autoAggregationDatapoints.value ?? this.lastAppliedDatapoints\n );\n return {\n datapoints,\n keepDataOnZoomIn: this.form.controls.autoAggregationKeepDataOnZoomIn.value ?? true\n };\n }\n\n private onRealtimeValueChange(realtime: boolean): void {\n let dateTimeContext: DateTimeContext;\n if (this.form.value.currentDateContextInterval !== 'custom') {\n dateTimeContext = this.datapointExplorerService.getDateTimeContextByInterval(\n this.form.value.currentDateContextInterval as Interval['id']\n );\n } else {\n const currentTimeSpanInMs =\n new Date(this.form.value.currentDateContextToDate).valueOf() -\n new Date(this.form.value.currentDateContextFromDate).valueOf();\n const dateTo = new Date();\n const dateFrom = new Date(dateTo.valueOf() - currentTimeSpanInMs);\n dateTimeContext = [dateFrom, dateTo];\n }\n\n this.isAutoModeActive.set(false);\n this.update({\n date: dateTimeContext,\n interval: this.form.value.currentDateContextInterval,\n realtime,\n aggregation: null,\n autoAggregation: null\n });\n }\n\n private startRealtime(): void {\n this.setRealtimeControlsLocked(true);\n\n this.realtimeSubscription = interval(this.REALTIME_INTERVAL)\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe(() => {\n if (!this.form.value.realtime) {\n this.realtimeSubscription.unsubscribe();\n return;\n }\n const newDateFrom = new Date(\n new Date(this.form.value.currentDateContextFromDate).valueOf() + this.REALTIME_INTERVAL\n );\n const newDateTo = new Date(\n new Date(this.form.value.currentDateContextToDate).valueOf() + this.REALTIME_INTERVAL\n );\n this.updateFormValues(\n {\n date: [newDateFrom, newDateTo],\n interval: this.form.value.currentDateContextInterval,\n realtime: true,\n aggregation: null\n },\n false\n ); // Don't emit during automatic realtime ticks\n });\n }\n\n private update(\n { date, interval, realtime, aggregation, autoAggregation = null },\n shouldEmit = true\n ): void {\n const { selectedAggregation, disabledAggregations } =\n this.datapointExplorerService.calculateAggregation(\n date,\n autoAggregation ? null : aggregation\n );\n this.disabledAggregations = disabledAggregations;\n this.updateFormValues(\n { date, interval, realtime, aggregation: selectedAggregation, autoAggregation },\n shouldEmit\n );\n }\n\n private createForm(context) {\n return this.formBuilder.group({\n temporaryUserSelectedFromDate: context.date[0].toISOString() as string,\n temporaryUserSelectedToDate: context.date[1].toISOString() as string,\n currentDateContextFromDate: context.date[0].toISOString() as string,\n currentDateContextToDate: context.date[1].toISOString() as string,\n currentDateContextInterval: context.interval || 'custom',\n realtime: context.realtime,\n aggregation: context.aggregation,\n autoAggregationEnabled: false,\n autoAggregationDatapoints: AUTO_AGGREGATION_DATAPOINTS.DEFAULT as number,\n autoAggregationKeepDataOnZoomIn: true\n });\n }\n\n private updateFormValues(\n { date, interval, realtime, aggregation, autoAggregation = null },\n shouldEmit = true\n ): void {\n const newFormValues = {\n temporaryUserSelectedFromDate: date[0].toISOString() as string,\n temporaryUserSelectedToDate: date[1].toISOString() as string,\n currentDateContextFromDate: date[0].toISOString() as string,\n currentDateContextToDate: date[1].toISOString() as string,\n realtime,\n currentDateContextInterval: interval || 'custom',\n aggregation: autoAggregation ? null : aggregation || null,\n autoAggregation\n };\n\n if (shouldEmit) {\n this.context.set(newFormValues);\n }\n if (autoAggregation?.datapoints != null) {\n this.lastAppliedDatapoints = this.clampToDatapointsBounds(autoAggregation.datapoints);\n }\n this.form.patchValue(\n {\n ...newFormValues,\n autoAggregationEnabled: !!autoAggregation,\n autoAggregationDatapoints:\n autoAggregation?.datapoints ?? this.form.value.autoAggregationDatapoints,\n autoAggregationKeepDataOnZoomIn:\n autoAggregation?.keepDataOnZoomIn ?? this.form.value.autoAggregationKeepDataOnZoomIn\n },\n { emitEvent: false }\n );\n }\n}\n","@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 }} — {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} — {{ 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 }} — {{ 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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import * as i0 from '@angular/core';
3
3
  import { inject, Injector, Injectable } from '@angular/core';
4
4
  import { PreviewService } from '@c8y/ngx-components';
5
5
  import { gettext } from '@c8y/ngx-components/gettext';
6
- import { AIService } from '@c8y/ngx-components/ai';
6
+ import { AIService, cumulocityApiRequestLabelProvider } from '@c8y/ngx-components/ai';
7
7
  import { defaultWidgetIds } from '@c8y/ngx-components/widgets/definitions';
8
8
  import { map, combineLatest, from, first } from 'rxjs';
9
9
  import { HTML_AGENT } from '@c8y/ngx-components/ai/agents/html';
@@ -90,7 +90,8 @@ class AIHtmlWidgetConfigFactory {
90
90
  toolCallConfig: {
91
91
  [this.queryToolName]: {
92
92
  executingLabel: gettext('Analyzing query…'),
93
- completedLabel: gettext('Query analyzed')
93
+ completedLabel: gettext('Query analyzed'),
94
+ labelProvider: cumulocityApiRequestLabelProvider
94
95
  },
95
96
  [this.codeToolName]: {
96
97
  executingLabel: gettext('Creating widget…'),
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs","sources":["../../widgets/definitions/html-widget-ai-config/html-widget-agent.definitions.ts","../../widgets/definitions/html-widget-ai-config/ai-html-widget-config.factory.ts","../../widgets/definitions/html-widget-ai-config/index.ts","../../widgets/definitions/html-widget-ai-config/c8y-ngx-components-widgets-definitions-html-widget-ai-config.ts"],"sourcesContent":["import type { ClientAgentDefinition } from '@c8y/ngx-components/ai';\nimport { HTML_AGENT } from '@c8y/ngx-components/ai/agents/html';\nimport { gettext } from '@c8y/ngx-components/gettext';\n\ndeclare const __MODE__: 'development' | 'production' | undefined;\n\n// Treat as \"production\" when run from Jest\nconst mode = (typeof __MODE__ !== 'undefined' ? __MODE__ : 'production') as\n | 'development'\n | 'production';\n\nexport const HTML_WIDGET_AGENT_DEFINITIONS: ClientAgentDefinition = {\n snapshot: mode === 'development',\n label: gettext('HTML Widget Code assistant'),\n definition: HTML_AGENT\n};\n","import { inject, Injectable, Injector } from '@angular/core';\nimport { ExtensionFactory, PreviewService } from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport {\n AIService,\n AIStreamResponse,\n WidgetAiChatSectionComponentConfig,\n ToolCallPart,\n AIAssistantMessage\n} from '@c8y/ngx-components/ai';\nimport { WidgetAiChatSectionComponent } from '@c8y/ngx-components/ai/agent-chat';\nimport type { WidgetConfigSectionDefinition } from '@c8y/ngx-components/context-dashboard';\nimport { WidgetConfigService } from '@c8y/ngx-components/context-dashboard';\nimport { defaultWidgetIds } from '@c8y/ngx-components/widgets/definitions';\nimport { combineLatest, first, from, map, Observable } from 'rxjs';\nimport { HTML_WIDGET_AGENT_DEFINITIONS } from './html-widget-agent.definitions';\nimport type {\n HtmlWidgetConfig,\n HtmlWidgetConfigService\n} from '@c8y/ngx-components/widgets/implementations/html-widget';\n\ntype CodeChangeToolCall = ToolCallPart<{ code: string }>;\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AIHtmlWidgetConfigFactory implements ExtensionFactory<WidgetConfigSectionDefinition> {\n private readonly betaPreviewService = inject(PreviewService);\n private readonly aiService = inject(AIService);\n /** The root injector (nb: components cannot be injected from here). */\n private readonly injector = inject(Injector);\n\n private readonly codeTag = 'c8y-code-extract';\n private readonly codeToolName = 'c8y-html-widget-code';\n private readonly queryToolName = 'cumulocity-api-request';\n private readonly widgetConfigService = inject(WidgetConfigService);\n\n private readonly aiWidgetConfigDefinition: WidgetConfigSectionDefinition<WidgetAiChatSectionComponent> =\n {\n widgetId: defaultWidgetIds.HTML,\n label: gettext('AI Code Assistant'),\n loadComponent: () =>\n import('@c8y/ngx-components/ai/agent-chat').then(m => m.WidgetAiChatSectionComponent),\n initialState: {\n // configuration to pass to WidgetAiChatSectionComponent\n agent: HTML_WIDGET_AGENT_DEFINITIONS,\n chatConfig: {\n title: gettext(\n 'I’m your AI Code Assistant, here to help you build powerful widgets for your dashboard.'\n ),\n welcomeText: gettext(\n 'Describe the widget you want or select one of the options below to get started.'\n ),\n showCumulativeUsage: true,\n showUsagePerMessage: true,\n showDeleteAction: true\n },\n\n loadComponentConfig: this.loadWidgetAiChatComponentConfig.bind(this),\n\n variables: this.widgetConfigService.currentConfig$.pipe(\n map((htmlWidgetConfig: HtmlWidgetConfig) => ({\n currentHtmlWidgetCode: htmlWidgetConfig?.config?.code || '',\n c8yContext: htmlWidgetConfig?.device || {}\n }))\n ),\n\n suggestions: [\n {\n label: gettext('Measurement widget'),\n prompt: gettext('Create a widget that shows the current measurement of this device.')\n },\n {\n label: gettext('Device status widget'),\n prompt: gettext('Create a widget that shows the status of my devices.')\n },\n {\n label: gettext('Critical alarm widget'),\n prompt: gettext('Create a widget that shows all critical alarms.')\n }\n ]\n },\n priority: 100,\n injector: this.injector\n };\n\n get(): Observable<WidgetConfigSectionDefinition[]> {\n return combineLatest([\n from(this.aiService.getAgentHealth()),\n this.betaPreviewService.getState$('ui.html-widget.v2').pipe(first())\n ]).pipe(\n map(([aiHealthCheck, state]) => {\n if (state && aiHealthCheck.isProviderConfigured) {\n return [this.aiWidgetConfigDefinition];\n }\n return [];\n })\n );\n }\n\n private async loadWidgetAiChatComponentConfig(\n componentInjector: Injector\n ): Promise<WidgetAiChatSectionComponentConfig> {\n const { HtmlWidgetConfigService, HtmlAiChatToolDetailsComponent } = await import(\n '@c8y/ngx-components/widgets/implementations/html-widget'\n );\n const htmlWidgetConfigService = componentInjector.get(HtmlWidgetConfigService);\n\n return {\n preprocessAgentMessage: (message, changed) =>\n this.preprocessAgentMessage(message, changed, htmlWidgetConfigService),\n\n assistantMessageDisplayConfig: {\n toolDetailsComponent: toolCallPart => {\n if (toolCallPart.toolName === this.codeToolName) {\n return HtmlAiChatToolDetailsComponent;\n }\n return undefined;\n },\n\n toolCallConfig: {\n [this.queryToolName]: {\n executingLabel: gettext('Analyzing query…'),\n completedLabel: gettext('Query analyzed')\n },\n [this.codeToolName]: {\n executingLabel: gettext('Creating widget…'),\n completedLabel: gettext('Widget created')\n }\n },\n // To match current behaviour and to help with development, for now we show the JSON for all tool calls\n showDefaultToolDetails: 'all'\n }\n };\n }\n\n private applyCurrentCode(code: string, htmlWidgetConfigService: HtmlWidgetConfigService) {\n const newConfig = {\n code: code,\n css: '',\n devMode: true,\n legacy: false,\n options: { advancedSecurity: false, cssEncapsulation: false }\n };\n htmlWidgetConfigService.configChanged$.next(newConfig);\n htmlWidgetConfigService.widgetConfigService.updateConfig({ config: newConfig });\n }\n\n protected preprocessAgentMessage(\n message: AIAssistantMessage,\n changedPart: AIStreamResponse['changedPart'],\n htmlWidgetConfigService: HtmlWidgetConfigService\n ): AIAssistantMessage {\n // Only apply this pre-processing to text parts, since that's what the agent will use to send the code\n if (!changedPart || changedPart.type !== 'text') {\n return message;\n }\n\n // Rewrite HTML content generated by the agent as text content as if it had come from a tool call\n\n // Find last tool named this.codeToolName in message.content, or undefined\n const codeTool = message.content.reduce<CodeChangeToolCall | undefined>(\n (last, part) =>\n 'toolName' in part && part.toolName === this.codeToolName\n ? (part as CodeChangeToolCall)\n : last,\n undefined\n );\n\n if (codeTool && codeTool.type !== 'tool-result') {\n // A code update tool call is in progress - accumulate text into input\n const input = `${codeTool.input?.code || ''}${changedPart.text}`;\n codeTool.input.code = input;\n changedPart.text = '';\n\n const closeIdx = input.indexOf(`</${this.codeTag}>`);\n if (closeIdx !== -1) {\n // Found closing tag - convert to result and start new step\n const beforeClose = input.substring(0, closeIdx);\n const afterClose = input.substring(closeIdx + `</${this.codeTag}>`.length);\n\n codeTool.input.code = beforeClose;\n codeTool.type = 'tool-result';\n\n // Always create a new (fake) step after this (just like a real AI), since final step can't contain tool calls\n message.content.push({ type: 'step-start' });\n if (afterClose.length > 0) {\n message.content.push({ type: 'text', text: afterClose });\n }\n\n // Since this is a fake tool call not a real one, the tool result callback won't trigger so do this manually\n this.applyCurrentCode(codeTool.input.code, htmlWidgetConfigService);\n } else {\n // Replace with a new instance so that change detection works\n message.content[message.content.findIndex(part => part === codeTool)] = { ...codeTool };\n }\n } else {\n // No in-progress code tag, so check for one\n const openIdx = changedPart.text.indexOf(`<${this.codeTag}>`);\n if (openIdx !== -1) {\n const afterOpen = changedPart.text.substring(openIdx + `<${this.codeTag}>`.length);\n changedPart.text = changedPart.text.substring(0, openIdx);\n\n // Start a new \"step\" to keep it separate and simple\n message.content.push({ type: 'step-start' });\n message.content.push({\n type: 'tool-input-streaming',\n toolName: this.codeToolName,\n toolCallId: this.codeToolName + message.content.length, // add part number just to ensure uniqueness\n input: { code: afterOpen }\n } satisfies CodeChangeToolCall);\n }\n }\n\n if (changedPart.text === '') {\n // Remove any empty changedPart from content\n message.content.splice(\n message.content.findIndex(part => part === changedPart),\n 1\n );\n }\n\n return message;\n }\n}\n","import { hookWidgetConfig } from '@c8y/ngx-components/context-dashboard';\nimport { AIHtmlWidgetConfigFactory } from './ai-html-widget-config.factory';\n\nexport const htmlWidgetAIChatProviders = [hookWidgetConfig(AIHtmlWidgetConfigFactory)];\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs","sources":["../../widgets/definitions/html-widget-ai-config/html-widget-agent.definitions.ts","../../widgets/definitions/html-widget-ai-config/ai-html-widget-config.factory.ts","../../widgets/definitions/html-widget-ai-config/index.ts","../../widgets/definitions/html-widget-ai-config/c8y-ngx-components-widgets-definitions-html-widget-ai-config.ts"],"sourcesContent":["import type { ClientAgentDefinition } from '@c8y/ngx-components/ai';\nimport { HTML_AGENT } from '@c8y/ngx-components/ai/agents/html';\nimport { gettext } from '@c8y/ngx-components/gettext';\n\ndeclare const __MODE__: 'development' | 'production' | undefined;\n\n// Treat as \"production\" when run from Jest\nconst mode = (typeof __MODE__ !== 'undefined' ? __MODE__ : 'production') as\n | 'development'\n | 'production';\n\nexport const HTML_WIDGET_AGENT_DEFINITIONS: ClientAgentDefinition = {\n snapshot: mode === 'development',\n label: gettext('HTML Widget Code assistant'),\n definition: HTML_AGENT\n};\n","import { inject, Injectable, Injector } from '@angular/core';\nimport { ExtensionFactory, PreviewService } from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport {\n AIService,\n AIStreamResponse,\n WidgetAiChatSectionComponentConfig,\n ToolCallPart,\n AIAssistantMessage,\n cumulocityApiRequestLabelProvider\n} from '@c8y/ngx-components/ai';\nimport { WidgetAiChatSectionComponent } from '@c8y/ngx-components/ai/agent-chat';\nimport type { WidgetConfigSectionDefinition } from '@c8y/ngx-components/context-dashboard';\nimport { WidgetConfigService } from '@c8y/ngx-components/context-dashboard';\nimport { defaultWidgetIds } from '@c8y/ngx-components/widgets/definitions';\nimport { combineLatest, first, from, map, Observable } from 'rxjs';\nimport { HTML_WIDGET_AGENT_DEFINITIONS } from './html-widget-agent.definitions';\nimport type {\n HtmlWidgetConfig,\n HtmlWidgetConfigService\n} from '@c8y/ngx-components/widgets/implementations/html-widget';\n\ntype CodeChangeToolCall = ToolCallPart<{ code: string }>;\n\n@Injectable({\n providedIn: 'root'\n})\nexport class AIHtmlWidgetConfigFactory implements ExtensionFactory<WidgetConfigSectionDefinition> {\n private readonly betaPreviewService = inject(PreviewService);\n private readonly aiService = inject(AIService);\n /** The root injector (nb: components cannot be injected from here). */\n private readonly injector = inject(Injector);\n\n private readonly codeTag = 'c8y-code-extract';\n private readonly codeToolName = 'c8y-html-widget-code';\n private readonly queryToolName = 'cumulocity-api-request';\n private readonly widgetConfigService = inject(WidgetConfigService);\n\n private readonly aiWidgetConfigDefinition: WidgetConfigSectionDefinition<WidgetAiChatSectionComponent> =\n {\n widgetId: defaultWidgetIds.HTML,\n label: gettext('AI Code Assistant'),\n loadComponent: () =>\n import('@c8y/ngx-components/ai/agent-chat').then(m => m.WidgetAiChatSectionComponent),\n initialState: {\n // configuration to pass to WidgetAiChatSectionComponent\n agent: HTML_WIDGET_AGENT_DEFINITIONS,\n chatConfig: {\n title: gettext(\n 'I’m your AI Code Assistant, here to help you build powerful widgets for your dashboard.'\n ),\n welcomeText: gettext(\n 'Describe the widget you want or select one of the options below to get started.'\n ),\n showCumulativeUsage: true,\n showUsagePerMessage: true,\n showDeleteAction: true\n },\n\n loadComponentConfig: this.loadWidgetAiChatComponentConfig.bind(this),\n\n variables: this.widgetConfigService.currentConfig$.pipe(\n map((htmlWidgetConfig: HtmlWidgetConfig) => ({\n currentHtmlWidgetCode: htmlWidgetConfig?.config?.code || '',\n c8yContext: htmlWidgetConfig?.device || {}\n }))\n ),\n\n suggestions: [\n {\n label: gettext('Measurement widget'),\n prompt: gettext('Create a widget that shows the current measurement of this device.')\n },\n {\n label: gettext('Device status widget'),\n prompt: gettext('Create a widget that shows the status of my devices.')\n },\n {\n label: gettext('Critical alarm widget'),\n prompt: gettext('Create a widget that shows all critical alarms.')\n }\n ]\n },\n priority: 100,\n injector: this.injector\n };\n\n get(): Observable<WidgetConfigSectionDefinition[]> {\n return combineLatest([\n from(this.aiService.getAgentHealth()),\n this.betaPreviewService.getState$('ui.html-widget.v2').pipe(first())\n ]).pipe(\n map(([aiHealthCheck, state]) => {\n if (state && aiHealthCheck.isProviderConfigured) {\n return [this.aiWidgetConfigDefinition];\n }\n return [];\n })\n );\n }\n\n private async loadWidgetAiChatComponentConfig(\n componentInjector: Injector\n ): Promise<WidgetAiChatSectionComponentConfig> {\n const { HtmlWidgetConfigService, HtmlAiChatToolDetailsComponent } = await import(\n '@c8y/ngx-components/widgets/implementations/html-widget'\n );\n const htmlWidgetConfigService = componentInjector.get(HtmlWidgetConfigService);\n\n return {\n preprocessAgentMessage: (message, changed) =>\n this.preprocessAgentMessage(message, changed, htmlWidgetConfigService),\n\n assistantMessageDisplayConfig: {\n toolDetailsComponent: toolCallPart => {\n if (toolCallPart.toolName === this.codeToolName) {\n return HtmlAiChatToolDetailsComponent;\n }\n return undefined;\n },\n\n toolCallConfig: {\n [this.queryToolName]: {\n executingLabel: gettext('Analyzing query…'),\n completedLabel: gettext('Query analyzed'),\n labelProvider: cumulocityApiRequestLabelProvider\n },\n [this.codeToolName]: {\n executingLabel: gettext('Creating widget…'),\n completedLabel: gettext('Widget created')\n }\n },\n // To match current behaviour and to help with development, for now we show the JSON for all tool calls\n showDefaultToolDetails: 'all'\n }\n };\n }\n\n private applyCurrentCode(code: string, htmlWidgetConfigService: HtmlWidgetConfigService) {\n const newConfig = {\n code: code,\n css: '',\n devMode: true,\n legacy: false,\n options: { advancedSecurity: false, cssEncapsulation: false }\n };\n htmlWidgetConfigService.configChanged$.next(newConfig);\n htmlWidgetConfigService.widgetConfigService.updateConfig({ config: newConfig });\n }\n\n protected preprocessAgentMessage(\n message: AIAssistantMessage,\n changedPart: AIStreamResponse['changedPart'],\n htmlWidgetConfigService: HtmlWidgetConfigService\n ): AIAssistantMessage {\n // Only apply this pre-processing to text parts, since that's what the agent will use to send the code\n if (!changedPart || changedPart.type !== 'text') {\n return message;\n }\n\n // Rewrite HTML content generated by the agent as text content as if it had come from a tool call\n\n // Find last tool named this.codeToolName in message.content, or undefined\n const codeTool = message.content.reduce<CodeChangeToolCall | undefined>(\n (last, part) =>\n 'toolName' in part && part.toolName === this.codeToolName\n ? (part as CodeChangeToolCall)\n : last,\n undefined\n );\n\n if (codeTool && codeTool.type !== 'tool-result') {\n // A code update tool call is in progress - accumulate text into input\n const input = `${codeTool.input?.code || ''}${changedPart.text}`;\n codeTool.input.code = input;\n changedPart.text = '';\n\n const closeIdx = input.indexOf(`</${this.codeTag}>`);\n if (closeIdx !== -1) {\n // Found closing tag - convert to result and start new step\n const beforeClose = input.substring(0, closeIdx);\n const afterClose = input.substring(closeIdx + `</${this.codeTag}>`.length);\n\n codeTool.input.code = beforeClose;\n codeTool.type = 'tool-result';\n\n // Always create a new (fake) step after this (just like a real AI), since final step can't contain tool calls\n message.content.push({ type: 'step-start' });\n if (afterClose.length > 0) {\n message.content.push({ type: 'text', text: afterClose });\n }\n\n // Since this is a fake tool call not a real one, the tool result callback won't trigger so do this manually\n this.applyCurrentCode(codeTool.input.code, htmlWidgetConfigService);\n } else {\n // Replace with a new instance so that change detection works\n message.content[message.content.findIndex(part => part === codeTool)] = { ...codeTool };\n }\n } else {\n // No in-progress code tag, so check for one\n const openIdx = changedPart.text.indexOf(`<${this.codeTag}>`);\n if (openIdx !== -1) {\n const afterOpen = changedPart.text.substring(openIdx + `<${this.codeTag}>`.length);\n changedPart.text = changedPart.text.substring(0, openIdx);\n\n // Start a new \"step\" to keep it separate and simple\n message.content.push({ type: 'step-start' });\n message.content.push({\n type: 'tool-input-streaming',\n toolName: this.codeToolName,\n toolCallId: this.codeToolName + message.content.length, // add part number just to ensure uniqueness\n input: { code: afterOpen }\n } satisfies CodeChangeToolCall);\n }\n }\n\n if (changedPart.text === '') {\n // Remove any empty changedPart from content\n message.content.splice(\n message.content.findIndex(part => part === changedPart),\n 1\n );\n }\n\n return message;\n }\n}\n","import { hookWidgetConfig } from '@c8y/ngx-components/context-dashboard';\nimport { AIHtmlWidgetConfigFactory } from './ai-html-widget-config.factory';\n\nexport const htmlWidgetAIChatProviders = [hookWidgetConfig(AIHtmlWidgetConfigFactory)];\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}