@meshmakers/octo-meshboard 3.4.320 → 3.4.330

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.
@@ -1,4 +1,4 @@
1
- import { FieldFilterOperatorsDto, CkTypeSelectorService, RuntimeEntitySelectDataSource as RuntimeEntitySelectDataSource$2, RuntimeEntityDialogDataSource as RuntimeEntityDialogDataSource$2, DeleteStrategiesDto, AssociationModOptionsDto, CkModelService, QueryModeDto, GraphDirectionDto, AttributeSelectorService, GraphQL, GetCkTypeAvailableQueryColumnsDtoGQL, SortOrdersDto, HealthService, TENANT_ID_PROVIDER, AssetRepoService, JobManagementService } from '@meshmakers/octo-services';
1
+ import { FieldFilterOperatorsDto, CkTypeSelectorService, RuntimeEntitySelectDataSource as RuntimeEntitySelectDataSource$2, RuntimeEntityDialogDataSource as RuntimeEntityDialogDataSource$2, DeleteStrategiesDto, AssociationModOptionsDto, CkModelService, QueryModeDto, GraphDirectionDto, AttributeSelectorService, GraphQL, GetCkTypeAvailableQueryColumnsDtoGQL, SortOrdersDto, SeriesResolutionSignalDto, HealthService, TENANT_ID_PROVIDER, AssetRepoService, JobManagementService } from '@meshmakers/octo-services';
2
2
  export { RuntimeEntityDialogDataSource, RuntimeEntitySelectDataSource, TENANT_ID_PROVIDER } from '@meshmakers/octo-services';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Injectable, inject, EventEmitter, forwardRef, Output, Input, ViewChild, ChangeDetectionStrategy, Component, Injector, EnvironmentInjector, ApplicationRef, signal, computed, Directive, ElementRef, NgZone, makeEnvironmentProviders, provideAppInitializer, InjectionToken, effect } from '@angular/core';
@@ -131,10 +131,10 @@ class GetSystemPersistentQueriesDtoGQL extends i1.Query {
131
131
  constructor(apollo) {
132
132
  super(apollo);
133
133
  }
134
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetSystemPersistentQueriesDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
135
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetSystemPersistentQueriesDtoGQL, providedIn: 'root' });
134
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetSystemPersistentQueriesDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
135
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetSystemPersistentQueriesDtoGQL, providedIn: 'root' });
136
136
  }
137
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetSystemPersistentQueriesDtoGQL, decorators: [{
137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetSystemPersistentQueriesDtoGQL, decorators: [{
138
138
  type: Injectable,
139
139
  args: [{
140
140
  providedIn: 'root'
@@ -378,8 +378,8 @@ class QuerySelectorComponent {
378
378
  setDisabledState(isDisabled) {
379
379
  this.disabled = isDisabled;
380
380
  }
381
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: QuerySelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
382
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: QuerySelectorComponent, isStandalone: true, selector: "mm-query-selector", inputs: { placeholder: "placeholder", hint: "hint", disabled: "disabled", acceptFamilies: "acceptFamilies" }, outputs: { querySelected: "querySelected", queriesLoaded: "queriesLoaded" }, providers: [
381
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QuerySelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
382
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: QuerySelectorComponent, isStandalone: true, selector: "mm-query-selector", inputs: { placeholder: "placeholder", hint: "hint", disabled: "disabled", acceptFamilies: "acceptFamilies" }, outputs: { querySelected: "querySelected", queriesLoaded: "queriesLoaded" }, providers: [
383
383
  {
384
384
  provide: NG_VALUE_ACCESSOR,
385
385
  useExisting: forwardRef(() => QuerySelectorComponent),
@@ -405,7 +405,7 @@ class QuerySelectorComponent {
405
405
  </div>
406
406
  `, isInline: true, styles: [".query-selector{width:100%}.field-hint{font-size:.85em;margin-top:4px;opacity:.7}\n"], dependencies: [{ kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
407
407
  }
408
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: QuerySelectorComponent, decorators: [{
408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QuerySelectorComponent, decorators: [{
409
409
  type: Component,
410
410
  args: [{ selector: 'mm-query-selector', standalone: true, imports: [
411
411
  EntitySelectInputComponent
@@ -486,10 +486,10 @@ class GetEntitiesByCkTypeDtoGQL extends i1.Query {
486
486
  constructor(apollo) {
487
487
  super(apollo);
488
488
  }
489
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetEntitiesByCkTypeDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
490
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetEntitiesByCkTypeDtoGQL, providedIn: 'root' });
489
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetEntitiesByCkTypeDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
490
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetEntitiesByCkTypeDtoGQL, providedIn: 'root' });
491
491
  }
492
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetEntitiesByCkTypeDtoGQL, decorators: [{
492
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetEntitiesByCkTypeDtoGQL, decorators: [{
493
493
  type: Injectable,
494
494
  args: [{
495
495
  providedIn: 'root'
@@ -669,8 +669,8 @@ class RuntimeEntitySelectorComponent {
669
669
  setDisabledState(isDisabled) {
670
670
  this.disabled = isDisabled;
671
671
  }
672
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RuntimeEntitySelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
673
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: RuntimeEntitySelectorComponent, isStandalone: true, selector: "mm-runtime-entity-selector", inputs: { ckTypeLabel: "ckTypeLabel", ckTypePlaceholder: "ckTypePlaceholder", ckTypeDialogTitle: "ckTypeDialogTitle", ckTypeHint: "ckTypeHint", ckTypeRequired: "ckTypeRequired", entityLabel: "entityLabel", entityPlaceholder: "entityPlaceholder", entityDialogTitle: "entityDialogTitle", entityHint: "entityHint", entityRequired: "entityRequired", showEntitySelector: "showEntitySelector", disabled: "disabled" }, outputs: { ckTypeSelected: "ckTypeSelected", ckTypeCleared: "ckTypeCleared", entitySelected: "entitySelected", entityCleared: "entityCleared", valueChange: "valueChange" }, providers: [
672
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RuntimeEntitySelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
673
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: RuntimeEntitySelectorComponent, isStandalone: true, selector: "mm-runtime-entity-selector", inputs: { ckTypeLabel: "ckTypeLabel", ckTypePlaceholder: "ckTypePlaceholder", ckTypeDialogTitle: "ckTypeDialogTitle", ckTypeHint: "ckTypeHint", ckTypeRequired: "ckTypeRequired", entityLabel: "entityLabel", entityPlaceholder: "entityPlaceholder", entityDialogTitle: "entityDialogTitle", entityHint: "entityHint", entityRequired: "entityRequired", showEntitySelector: "showEntitySelector", disabled: "disabled" }, outputs: { ckTypeSelected: "ckTypeSelected", ckTypeCleared: "ckTypeCleared", entitySelected: "entitySelected", entityCleared: "entityCleared", valueChange: "valueChange" }, providers: [
674
674
  {
675
675
  provide: NG_VALUE_ACCESSOR,
676
676
  useExisting: forwardRef(() => RuntimeEntitySelectorComponent),
@@ -725,7 +725,7 @@ class RuntimeEntitySelectorComponent {
725
725
  </div>
726
726
  `, isInline: true, styles: [".runtime-entity-selector{display:flex;flex-direction:column;gap:16px}.form-field{display:flex;flex-direction:column;gap:4px}.form-field label{font-weight:500}.form-field.disabled{opacity:.6}.field-hint{font-size:.85em;margin:0;opacity:.7}.required{color:#dc3545}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
727
727
  }
728
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RuntimeEntitySelectorComponent, decorators: [{
728
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RuntimeEntitySelectorComponent, decorators: [{
729
729
  type: Component,
730
730
  args: [{ selector: 'mm-runtime-entity-selector', standalone: true, imports: [
731
731
  CommonModule,
@@ -833,15 +833,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
833
833
  * Used by all widget types when they are not properly configured.
834
834
  */
835
835
  class WidgetNotConfiguredComponent {
836
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetNotConfiguredComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
837
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", type: WidgetNotConfiguredComponent, isStandalone: true, selector: "mm-widget-not-configured", ngImport: i0, template: `
836
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetNotConfiguredComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
837
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: WidgetNotConfiguredComponent, isStandalone: true, selector: "mm-widget-not-configured", ngImport: i0, template: `
838
838
  <div class="widget-not-configured">
839
839
  <span class="warning-icon">!</span>
840
840
  <span class="message">Widget not configured</span>
841
841
  </div>
842
842
  `, isInline: true, styles: [".widget-not-configured{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:8px;color:var(--kendo-color-error, #dc3545)}.warning-icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:#dc35451a;font-weight:700;font-size:1.25rem}.message{font-size:.875rem;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.Eager });
843
843
  }
844
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetNotConfiguredComponent, decorators: [{
844
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetNotConfiguredComponent, decorators: [{
845
845
  type: Component,
846
846
  args: [{ selector: 'mm-widget-not-configured', standalone: true, imports: [CommonModule], template: `
847
847
  <div class="widget-not-configured">
@@ -877,10 +877,10 @@ class GetDashboardsDtoGQL extends i1.Query {
877
877
  constructor(apollo) {
878
878
  super(apollo);
879
879
  }
880
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardsDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
881
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardsDtoGQL, providedIn: 'root' });
880
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardsDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
881
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardsDtoGQL, providedIn: 'root' });
882
882
  }
883
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardsDtoGQL, decorators: [{
883
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardsDtoGQL, decorators: [{
884
884
  type: Injectable,
885
885
  args: [{
886
886
  providedIn: 'root'
@@ -911,10 +911,10 @@ class CreateDashboardDtoGQL extends i1.Mutation {
911
911
  constructor(apollo) {
912
912
  super(apollo);
913
913
  }
914
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CreateDashboardDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
915
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CreateDashboardDtoGQL, providedIn: 'root' });
914
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CreateDashboardDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
915
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CreateDashboardDtoGQL, providedIn: 'root' });
916
916
  }
917
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CreateDashboardDtoGQL, decorators: [{
917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CreateDashboardDtoGQL, decorators: [{
918
918
  type: Injectable,
919
919
  args: [{
920
920
  providedIn: 'root'
@@ -945,10 +945,10 @@ class UpdateDashboardDtoGQL extends i1.Mutation {
945
945
  constructor(apollo) {
946
946
  super(apollo);
947
947
  }
948
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: UpdateDashboardDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
949
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: UpdateDashboardDtoGQL, providedIn: 'root' });
948
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: UpdateDashboardDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
949
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: UpdateDashboardDtoGQL, providedIn: 'root' });
950
950
  }
951
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: UpdateDashboardDtoGQL, decorators: [{
951
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: UpdateDashboardDtoGQL, decorators: [{
952
952
  type: Injectable,
953
953
  args: [{
954
954
  providedIn: 'root'
@@ -983,10 +983,10 @@ class CreateDashboardWidgetDtoGQL extends i1.Mutation {
983
983
  constructor(apollo) {
984
984
  super(apollo);
985
985
  }
986
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CreateDashboardWidgetDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
987
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CreateDashboardWidgetDtoGQL, providedIn: 'root' });
986
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CreateDashboardWidgetDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
987
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CreateDashboardWidgetDtoGQL, providedIn: 'root' });
988
988
  }
989
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: CreateDashboardWidgetDtoGQL, decorators: [{
989
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: CreateDashboardWidgetDtoGQL, decorators: [{
990
990
  type: Injectable,
991
991
  args: [{
992
992
  providedIn: 'root'
@@ -1021,10 +1021,10 @@ class UpdateDashboardWidgetDtoGQL extends i1.Mutation {
1021
1021
  constructor(apollo) {
1022
1022
  super(apollo);
1023
1023
  }
1024
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: UpdateDashboardWidgetDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
1025
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: UpdateDashboardWidgetDtoGQL, providedIn: 'root' });
1024
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: UpdateDashboardWidgetDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
1025
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: UpdateDashboardWidgetDtoGQL, providedIn: 'root' });
1026
1026
  }
1027
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: UpdateDashboardWidgetDtoGQL, decorators: [{
1027
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: UpdateDashboardWidgetDtoGQL, decorators: [{
1028
1028
  type: Injectable,
1029
1029
  args: [{
1030
1030
  providedIn: 'root'
@@ -1045,10 +1045,10 @@ class DeleteEntitiesDtoGQL extends i1.Mutation {
1045
1045
  constructor(apollo) {
1046
1046
  super(apollo);
1047
1047
  }
1048
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: DeleteEntitiesDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
1049
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: DeleteEntitiesDtoGQL, providedIn: 'root' });
1048
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DeleteEntitiesDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
1049
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DeleteEntitiesDtoGQL, providedIn: 'root' });
1050
1050
  }
1051
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: DeleteEntitiesDtoGQL, decorators: [{
1051
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DeleteEntitiesDtoGQL, decorators: [{
1052
1052
  type: Injectable,
1053
1053
  args: [{
1054
1054
  providedIn: 'root'
@@ -1098,10 +1098,10 @@ class GetDashboardWithWidgetsDtoGQL extends i1.Query {
1098
1098
  constructor(apollo) {
1099
1099
  super(apollo);
1100
1100
  }
1101
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardWithWidgetsDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
1102
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardWithWidgetsDtoGQL, providedIn: 'root' });
1101
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardWithWidgetsDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
1102
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardWithWidgetsDtoGQL, providedIn: 'root' });
1103
1103
  }
1104
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardWithWidgetsDtoGQL, decorators: [{
1104
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardWithWidgetsDtoGQL, decorators: [{
1105
1105
  type: Injectable,
1106
1106
  args: [{
1107
1107
  providedIn: 'root'
@@ -1410,10 +1410,10 @@ class WidgetRegistryService {
1410
1410
  document.head.appendChild(style);
1411
1411
  WidgetRegistryService.scrollbarStylesInjected = true;
1412
1412
  }
1413
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1414
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetRegistryService, providedIn: 'root' });
1413
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1414
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetRegistryService, providedIn: 'root' });
1415
1415
  }
1416
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetRegistryService, decorators: [{
1416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetRegistryService, decorators: [{
1417
1417
  type: Injectable,
1418
1418
  args: [{
1419
1419
  providedIn: 'root'
@@ -1739,11 +1739,11 @@ class MeshBoardPersistenceService {
1739
1739
  encodeVariablesInDescription(description, variables, timeFilter, entitySelectors, autoRefreshSeconds, timeZoneMode) {
1740
1740
  // Filter out timeFilter and entitySelector variables (they are derived, not persisted directly)
1741
1741
  const staticVariables = variables?.filter(v => v.source !== 'timeFilter' && v.source !== 'entitySelector');
1742
- // Check if there's anything to encode. 'local' is the default, so only the
1743
- // non-default 'utc' mode needs persisting.
1742
+ // Check if there's anything to encode. 'local' is the default, so any other
1743
+ // value 'utc' or an IANA id (AB#4190) — needs persisting.
1744
1744
  const hasEntitySelectors = entitySelectors && entitySelectors.length > 0;
1745
1745
  const hasAutoRefresh = !!autoRefreshSeconds && autoRefreshSeconds > 0;
1746
- const hasTimeZoneMode = timeZoneMode === 'utc';
1746
+ const hasTimeZoneMode = !!timeZoneMode && timeZoneMode !== 'local';
1747
1747
  if ((!staticVariables || staticVariables.length === 0) &&
1748
1748
  !timeFilter?.enabled && !hasEntitySelectors && !hasAutoRefresh && !hasTimeZoneMode) {
1749
1749
  return description;
@@ -1814,7 +1814,7 @@ class MeshBoardPersistenceService {
1814
1814
  description,
1815
1815
  variables: parsed.variables ?? [],
1816
1816
  timeFilter: parsed.timeFilter,
1817
- timeZoneMode: parsed.timeZoneMode === 'utc' || parsed.timeZoneMode === 'local' ? parsed.timeZoneMode : undefined,
1817
+ timeZoneMode: typeof parsed.timeZoneMode === 'string' && parsed.timeZoneMode !== 'local' ? parsed.timeZoneMode : undefined,
1818
1818
  entitySelectors: parsed.entitySelectors,
1819
1819
  autoRefreshSeconds: typeof parsed.autoRefreshSeconds === 'number' ? parsed.autoRefreshSeconds : undefined
1820
1820
  };
@@ -1824,10 +1824,10 @@ class MeshBoardPersistenceService {
1824
1824
  return { description, variables: [] };
1825
1825
  }
1826
1826
  }
1827
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardPersistenceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1828
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardPersistenceService, providedIn: 'root' });
1827
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardPersistenceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1828
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardPersistenceService, providedIn: 'root' });
1829
1829
  }
1830
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardPersistenceService, decorators: [{
1830
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardPersistenceService, decorators: [{
1831
1831
  type: Injectable,
1832
1832
  args: [{
1833
1833
  providedIn: 'root'
@@ -1973,10 +1973,10 @@ class MeshBoardGridService {
1973
1973
  }
1974
1974
  return { col: 1, row: maxRow };
1975
1975
  }
1976
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardGridService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1977
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardGridService, providedIn: 'root' });
1976
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardGridService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1977
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardGridService, providedIn: 'root' });
1978
1978
  }
1979
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardGridService, decorators: [{
1979
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardGridService, decorators: [{
1980
1980
  type: Injectable,
1981
1981
  args: [{
1982
1982
  providedIn: 'root'
@@ -2533,6 +2533,21 @@ class MeshBoardStateService {
2533
2533
  }
2534
2534
  return { from: range.from, to: range.to };
2535
2535
  }
2536
+ /**
2537
+ * The IANA time zone to forward to the resolution-aware series query so calendar
2538
+ * rollups are selected in the board's zone (AB#4190). Maps the board mode:
2539
+ * `'utc'` → `'UTC'`, an IANA id → itself, and `'local'` → `undefined` (the browser's
2540
+ * own zone has no server-side meaning, so the resolver stays on UTC — the same
2541
+ * basis its calendar rungs use by default). The result is consistent with the zone
2542
+ * `resolveCurrentTimeRange()` used to compute the `{from, to}` window.
2543
+ */
2544
+ resolveStreamDataTimeZone() {
2545
+ const mode = this.timeZoneMode();
2546
+ if (mode === 'local') {
2547
+ return undefined;
2548
+ }
2549
+ return mode === 'utc' ? 'UTC' : mode;
2550
+ }
2536
2551
  /**
2537
2552
  * Stores the source rtIds resolved from an entity selector's current
2538
2553
  * selection. Called by the view component after a selection resolves (the
@@ -2682,10 +2697,10 @@ class MeshBoardStateService {
2682
2697
  const currentVars = this.getVariables().filter(v => !(v.source === 'entitySelector' && v.entitySelectorId === selectorId));
2683
2698
  this.updateVariables(currentVars);
2684
2699
  }
2685
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2686
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardStateService, providedIn: 'root' });
2700
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2701
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardStateService, providedIn: 'root' });
2687
2702
  }
2688
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardStateService, decorators: [{
2703
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardStateService, decorators: [{
2689
2704
  type: Injectable,
2690
2705
  args: [{
2691
2706
  providedIn: 'root'
@@ -2730,10 +2745,10 @@ class GetDashboardEntityDtoGQL extends i1.Query {
2730
2745
  constructor(apollo) {
2731
2746
  super(apollo);
2732
2747
  }
2733
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardEntityDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2734
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardEntityDtoGQL, providedIn: 'root' });
2748
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardEntityDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2749
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardEntityDtoGQL, providedIn: 'root' });
2735
2750
  }
2736
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetDashboardEntityDtoGQL, decorators: [{
2751
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetDashboardEntityDtoGQL, decorators: [{
2737
2752
  type: Injectable,
2738
2753
  args: [{
2739
2754
  providedIn: 'root'
@@ -2763,10 +2778,10 @@ class GetCkModelsWithStateDtoGQL extends i1.Query {
2763
2778
  constructor(apollo) {
2764
2779
  super(apollo);
2765
2780
  }
2766
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkModelsWithStateDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2767
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkModelsWithStateDtoGQL, providedIn: 'root' });
2781
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkModelsWithStateDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2782
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkModelsWithStateDtoGQL, providedIn: 'root' });
2768
2783
  }
2769
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkModelsWithStateDtoGQL, decorators: [{
2784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkModelsWithStateDtoGQL, decorators: [{
2770
2785
  type: Injectable,
2771
2786
  args: [{
2772
2787
  providedIn: 'root'
@@ -2815,10 +2830,10 @@ class ExecuteRuntimeQueryDtoGQL extends i1.Query {
2815
2830
  constructor(apollo) {
2816
2831
  super(apollo);
2817
2832
  }
2818
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ExecuteRuntimeQueryDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2819
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ExecuteRuntimeQueryDtoGQL, providedIn: 'root' });
2833
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ExecuteRuntimeQueryDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2834
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ExecuteRuntimeQueryDtoGQL, providedIn: 'root' });
2820
2835
  }
2821
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ExecuteRuntimeQueryDtoGQL, decorators: [{
2836
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ExecuteRuntimeQueryDtoGQL, decorators: [{
2822
2837
  type: Injectable,
2823
2838
  args: [{
2824
2839
  providedIn: 'root'
@@ -2874,10 +2889,38 @@ class ExecuteStreamDataQueryDtoGQL extends i1.Query {
2874
2889
  constructor(apollo) {
2875
2890
  super(apollo);
2876
2891
  }
2877
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ExecuteStreamDataQueryDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2878
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ExecuteStreamDataQueryDtoGQL, providedIn: 'root' });
2892
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ExecuteStreamDataQueryDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2893
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ExecuteStreamDataQueryDtoGQL, providedIn: 'root' });
2879
2894
  }
2880
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ExecuteStreamDataQueryDtoGQL, decorators: [{
2895
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ExecuteStreamDataQueryDtoGQL, decorators: [{
2896
+ type: Injectable,
2897
+ args: [{
2898
+ providedIn: 'root'
2899
+ }]
2900
+ }], ctorParameters: () => [{ type: i1.Apollo }] });
2901
+
2902
+ const GetStreamDataQueryArchiveDocumentDto = gql `
2903
+ query getStreamDataQueryArchive($rtId: OctoObjectId!) {
2904
+ streamData {
2905
+ streamDataQuery(rtId: $rtId) {
2906
+ items {
2907
+ queryRtId
2908
+ associatedCkTypeId
2909
+ archiveRtId
2910
+ }
2911
+ }
2912
+ }
2913
+ }
2914
+ `;
2915
+ class GetStreamDataQueryArchiveDtoGQL extends i1.Query {
2916
+ document = GetStreamDataQueryArchiveDocumentDto;
2917
+ constructor(apollo) {
2918
+ super(apollo);
2919
+ }
2920
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetStreamDataQueryArchiveDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2921
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetStreamDataQueryArchiveDtoGQL, providedIn: 'root' });
2922
+ }
2923
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetStreamDataQueryArchiveDtoGQL, decorators: [{
2881
2924
  type: Injectable,
2882
2925
  args: [{
2883
2926
  providedIn: 'root'
@@ -2904,10 +2947,58 @@ class ResolveSeriesQueryDtoGQL extends i1.Query {
2904
2947
  constructor(apollo) {
2905
2948
  super(apollo);
2906
2949
  }
2907
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ResolveSeriesQueryDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2908
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ResolveSeriesQueryDtoGQL, providedIn: 'root' });
2950
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ResolveSeriesQueryDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2951
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ResolveSeriesQueryDtoGQL, providedIn: 'root' });
2952
+ }
2953
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ResolveSeriesQueryDtoGQL, decorators: [{
2954
+ type: Injectable,
2955
+ args: [{
2956
+ providedIn: 'root'
2957
+ }]
2958
+ }], ctorParameters: () => [{ type: i1.Apollo }] });
2959
+
2960
+ const TransientDownsamplingDocumentDto = gql `
2961
+ query transientDownsampling($archiveRtId: OctoObjectId!, $from: DateTime!, $to: DateTime!, $limit: Int!, $columnPaths: [StreamDataQueryColumnInput!]!, $rtIds: [OctoObjectId], $fieldFilter: [FieldFilter]) {
2962
+ streamData {
2963
+ transientStreamDataQuery {
2964
+ downsampling(
2965
+ archiveRtId: $archiveRtId
2966
+ from: $from
2967
+ to: $to
2968
+ limit: $limit
2969
+ columnPaths: $columnPaths
2970
+ rtIds: $rtIds
2971
+ fieldFilter: $fieldFilter
2972
+ ) {
2973
+ items {
2974
+ rows {
2975
+ totalCount
2976
+ items {
2977
+ rtId
2978
+ timestamp
2979
+ cells {
2980
+ items {
2981
+ attributePath
2982
+ value
2983
+ }
2984
+ }
2985
+ }
2986
+ }
2987
+ }
2988
+ }
2989
+ }
2990
+ }
2991
+ }
2992
+ `;
2993
+ class TransientDownsamplingDtoGQL extends i1.Query {
2994
+ document = TransientDownsamplingDocumentDto;
2995
+ constructor(apollo) {
2996
+ super(apollo);
2997
+ }
2998
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TransientDownsamplingDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
2999
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TransientDownsamplingDtoGQL, providedIn: 'root' });
2909
3000
  }
2910
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ResolveSeriesQueryDtoGQL, decorators: [{
3001
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TransientDownsamplingDtoGQL, decorators: [{
2911
3002
  type: Injectable,
2912
3003
  args: [{
2913
3004
  providedIn: 'root'
@@ -2936,6 +3027,9 @@ class QueryExecutorService {
2936
3027
  streamDataGql = inject(ExecuteStreamDataQueryDtoGQL);
2937
3028
  persistentQueriesGql = inject(GetSystemPersistentQueriesDtoGQL);
2938
3029
  resolveSeriesGql = inject(ResolveSeriesQueryDtoGQL);
3030
+ queryArchiveGql = inject(GetStreamDataQueryArchiveDtoGQL);
3031
+ downsampleGql = inject(TransientDownsamplingDtoGQL);
3032
+ entitiesGql = inject(GetEntitiesByCkTypeDtoGQL);
2939
3033
  /**
2940
3034
  * Cache of resolved query families, keyed by query rtId. Filled lazily for
2941
3035
  * legacy widget configs that pre-date the `queryFamily` field — saves a
@@ -3060,6 +3154,70 @@ class QueryExecutorService {
3060
3154
  diagnostic: decision.diagnostic ?? null
3061
3155
  };
3062
3156
  }
3157
+ /**
3158
+ * Resolution-aware routing (AB#4290): reads a persisted stream-data query's base archive rtId
3159
+ * and target CK type WITHOUT executing the query (the `rows` sub-connection is not selected), so
3160
+ * a widget can feed the archive to {@link resolveSeriesQuery} and use the CK type to resolve
3161
+ * per-series labels. Returns null when the query is missing or has no archive.
3162
+ */
3163
+ async fetchQueryArchive(queryRtId) {
3164
+ const result = await firstValueFrom(this.queryArchiveGql.fetch({ variables: { rtId: queryRtId }, fetchPolicy: 'cache-first' }));
3165
+ const item = result.data?.streamData?.streamDataQuery?.items?.[0];
3166
+ if (item?.archiveRtId == null) {
3167
+ return null;
3168
+ }
3169
+ return { archiveRtId: String(item.archiveRtId), ckTypeId: item.associatedCkTypeId != null ? String(item.associatedCkTypeId) : null };
3170
+ }
3171
+ /**
3172
+ * Resolution-aware routing (AB#4290): runs the AB#4233 downsampling query against an explicit
3173
+ * archive rtId (the rollup/base chosen by {@link resolveSeriesQuery}), reducing `sourcePath`
3174
+ * with `aggregation` to at most `limit` buckets. The transient downsampling groups by bin
3175
+ * (not by source rtId), so callers that need per-series lines scope `rtIds` to one source
3176
+ * entity per call. Returns the unified rows; each row's single value cell carries the reduced
3177
+ * value under its wire column name (e.g. `amountvalue_sum`) alongside the bin `timestamp`.
3178
+ */
3179
+ async downsampleByArchive(params) {
3180
+ const result = await firstValueFrom(this.downsampleGql.fetch({
3181
+ variables: {
3182
+ archiveRtId: params.archiveRtId,
3183
+ from: params.from,
3184
+ to: params.to,
3185
+ limit: params.limit,
3186
+ columnPaths: [{ attributePath: params.sourcePath, aggregationType: params.aggregation }],
3187
+ rtIds: params.rtIds && params.rtIds.length > 0 ? params.rtIds : undefined,
3188
+ fieldFilter: params.fieldFilter ?? undefined
3189
+ },
3190
+ fetchPolicy: 'network-only'
3191
+ }));
3192
+ const rows = result.data?.streamData?.transientStreamDataQuery?.downsampling?.items?.[0]?.rows?.items;
3193
+ return this.mapStreamDataRows(rows);
3194
+ }
3195
+ /**
3196
+ * Best-effort per-series labels for resolution-aware fan-out (AB#4290): reads each source
3197
+ * entity's attribute matching `labelField` (canonical, case/underscore-insensitive so an archive
3198
+ * column like `obis_code` maps to the CK attribute `obisCode`). Entities that fail to load or
3199
+ * lack the attribute are simply omitted; the caller falls back to the rtId. Returns a
3200
+ * `rtId → label` map.
3201
+ */
3202
+ async fetchSeriesLabels(ckTypeId, rtIds, labelField) {
3203
+ const map = new Map();
3204
+ const canon = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, '');
3205
+ const wanted = canon(labelField);
3206
+ await Promise.all(rtIds.map(async (rtId) => {
3207
+ try {
3208
+ const res = await firstValueFrom(this.entitiesGql.fetch({ variables: { ckTypeId, rtId, first: 1 } }));
3209
+ const item = res.data?.runtime?.runtimeEntities?.items?.[0];
3210
+ const attr = item?.attributes?.items?.find(a => !!a?.attributeName && canon(a.attributeName) === wanted);
3211
+ if (attr?.value != null) {
3212
+ map.set(rtId, String(attr.value));
3213
+ }
3214
+ }
3215
+ catch {
3216
+ // Labels are best-effort; the fan-out falls back to the rtId.
3217
+ }
3218
+ }));
3219
+ return map;
3220
+ }
3063
3221
  buildStreamDataArg(args) {
3064
3222
  // Skip the entire `arg` field when the caller has nothing to override —
3065
3223
  // the persisted query then runs with its intrinsic from/to/limit and the
@@ -3146,10 +3304,10 @@ class QueryExecutorService {
3146
3304
  }
3147
3305
  return result;
3148
3306
  }
3149
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: QueryExecutorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3150
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: QueryExecutorService, providedIn: 'root' });
3307
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryExecutorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3308
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryExecutorService, providedIn: 'root' });
3151
3309
  }
3152
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: QueryExecutorService, decorators: [{
3310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: QueryExecutorService, decorators: [{
3153
3311
  type: Injectable,
3154
3312
  args: [{ providedIn: 'root' }]
3155
3313
  }] });
@@ -3190,10 +3348,10 @@ class GetAssociationTargetsDtoGQL extends i1.Query {
3190
3348
  constructor(apollo) {
3191
3349
  super(apollo);
3192
3350
  }
3193
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetAssociationTargetsDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
3194
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetAssociationTargetsDtoGQL, providedIn: 'root' });
3351
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetAssociationTargetsDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
3352
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetAssociationTargetsDtoGQL, providedIn: 'root' });
3195
3353
  }
3196
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetAssociationTargetsDtoGQL, decorators: [{
3354
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetAssociationTargetsDtoGQL, decorators: [{
3197
3355
  type: Injectable,
3198
3356
  args: [{
3199
3357
  providedIn: 'root'
@@ -3222,10 +3380,10 @@ class GetCkTypeAttributesForMeshboardDtoGQL extends i1.Query {
3222
3380
  constructor(apollo) {
3223
3381
  super(apollo);
3224
3382
  }
3225
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkTypeAttributesForMeshboardDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
3226
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkTypeAttributesForMeshboardDtoGQL, providedIn: 'root' });
3383
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkTypeAttributesForMeshboardDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
3384
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkTypeAttributesForMeshboardDtoGQL, providedIn: 'root' });
3227
3385
  }
3228
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkTypeAttributesForMeshboardDtoGQL, decorators: [{
3386
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkTypeAttributesForMeshboardDtoGQL, decorators: [{
3229
3387
  type: Injectable,
3230
3388
  args: [{
3231
3389
  providedIn: 'root'
@@ -3412,10 +3570,10 @@ class MeshBoardVariableService {
3412
3570
  defaultValue
3413
3571
  };
3414
3572
  }
3415
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardVariableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3416
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardVariableService, providedIn: 'root' });
3573
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardVariableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3574
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardVariableService, providedIn: 'root' });
3417
3575
  }
3418
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardVariableService, decorators: [{
3576
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardVariableService, decorators: [{
3419
3577
  type: Injectable,
3420
3578
  args: [{
3421
3579
  providedIn: 'root'
@@ -3845,10 +4003,10 @@ class MeshBoardDataService {
3845
4003
  value
3846
4004
  }));
3847
4005
  }
3848
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3849
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardDataService, providedIn: 'root' });
4006
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4007
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardDataService, providedIn: 'root' });
3850
4008
  }
3851
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardDataService, decorators: [{
4009
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardDataService, decorators: [{
3852
4010
  type: Injectable,
3853
4011
  args: [{
3854
4012
  providedIn: 'root'
@@ -3895,10 +4053,10 @@ class WidgetFactoryService {
3895
4053
  getDefaultSize(type) {
3896
4054
  return this.registry.getDefaultSize(type);
3897
4055
  }
3898
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetFactoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3899
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetFactoryService, providedIn: 'root' });
4056
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetFactoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4057
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetFactoryService, providedIn: 'root' });
3900
4058
  }
3901
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetFactoryService, decorators: [{
4059
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetFactoryService, decorators: [{
3902
4060
  type: Injectable,
3903
4061
  args: [{
3904
4062
  providedIn: 'root'
@@ -4013,10 +4171,10 @@ class EditModeStateService {
4013
4171
  this._isSaving.set(false);
4014
4172
  this.snapshot = null;
4015
4173
  }
4016
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EditModeStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4017
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EditModeStateService, providedIn: 'root' });
4174
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EditModeStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4175
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EditModeStateService, providedIn: 'root' });
4018
4176
  }
4019
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EditModeStateService, decorators: [{
4177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EditModeStateService, decorators: [{
4020
4178
  type: Injectable,
4021
4179
  args: [{
4022
4180
  providedIn: 'root'
@@ -4082,10 +4240,10 @@ class AutoRefreshTimerService {
4082
4240
  ngOnDestroy() {
4083
4241
  this.stop();
4084
4242
  }
4085
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AutoRefreshTimerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4086
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AutoRefreshTimerService });
4243
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AutoRefreshTimerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4244
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AutoRefreshTimerService });
4087
4245
  }
4088
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AutoRefreshTimerService, decorators: [{
4246
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AutoRefreshTimerService, decorators: [{
4089
4247
  type: Injectable
4090
4248
  }] });
4091
4249
 
@@ -4298,10 +4456,10 @@ class EntityCardWidgetComponent {
4298
4456
  .replace(/^./, str => str.toUpperCase())
4299
4457
  .trim();
4300
4458
  }
4301
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntityCardWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4302
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: EntityCardWidgetComponent, isStandalone: true, selector: "mm-entity-card-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"entity-card\" [class.no-data]=\"!data()\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>Loading...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else if (data()) {\n <!-- Header (like UML class name) -->\n @if (config.showHeader !== false) {\n <div class=\"entity-header\">\n <span class=\"entity-stereotype\">&laquo;{{ entityTypeName() }}&raquo;</span>\n <span class=\"entity-name\">{{ displayName() }}</span>\n </div>\n }\n\n <!-- Attributes Section (like UML attributes) -->\n @if (config.showAttributes !== false && filteredAttributes().length > 0) {\n <div class=\"entity-attributes\">\n @for (attr of filteredAttributes(); track attr.attributeName) {\n <div class=\"attribute-row\">\n <span class=\"attribute-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"attribute-value\">\n <mm-property-value-display\n [value]=\"attr.value\"\n [type]=\"inferAttributeType(attr.value)\"\n [attributeName]=\"attr.attributeName\">\n </mm-property-value-display>\n </span>\n </div>\n }\n </div>\n }\n\n <!-- Metadata Footer -->\n <div class=\"entity-footer\">\n <span class=\"entity-id\" title=\"Runtime ID\">{{ data()!.rtId }}</span>\n </div>\n } @else {\n <div class=\"entity-empty\">\n <span class=\"entity-empty-text\">{{ emptyMessage() }}</span>\n </div>\n }\n</div>\n", styles: [".entity-card{display:flex;flex-direction:column;height:100%;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;overflow:hidden;background:var(--kendo-color-surface, #fff)}.entity-card.no-data,.entity-card.loading,.entity-card.error{justify-content:center;align-items:center}.entity-card.loading{color:var(--kendo-color-primary, #0d6efd)}.entity-card.error{color:var(--kendo-color-error, #dc3545)}.loading-indicator{font-size:.875rem;font-style:italic}.error-message{font-size:.875rem;padding:12px;text-align:center}.entity-header{display:flex;flex-direction:column;align-items:center;padding:12px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);text-align:center}.entity-header .entity-stereotype{font-size:.75rem;font-style:italic;opacity:.9;margin-bottom:2px}.entity-header .entity-name{font-size:1rem;font-weight:600}.entity-attributes{flex:1;padding:8px 0;overflow-y:auto}.entity-attributes .attribute-row{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;border-bottom:1px solid var(--kendo-color-border-alt, #e9ecef);font-size:.8125rem}.entity-attributes .attribute-row:last-child{border-bottom:none}.entity-attributes .attribute-row:hover{background:var(--kendo-color-surface-alt, #f8f9fa)}.entity-attributes .attribute-name{color:var(--kendo-color-subtle, #6c757d);flex-shrink:0;margin-right:12px}.entity-attributes .attribute-value{color:var(--kendo-color-on-surface, #212529);font-weight:500;text-align:right;word-break:break-word;min-width:0;flex:1}.entity-footer{padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-top:1px solid var(--kendo-color-border, #dee2e6)}.entity-footer .entity-id{font-size:.6875rem;font-family:monospace;color:var(--kendo-color-subtle, #6c757d)}.no-data-message{font-size:.875rem}.entity-empty{display:flex;align-items:center;justify-content:center;height:100%;padding:8px;text-align:center}.entity-empty-text{font-size:.875rem;color:var(--kendo-color-subtle, #6c757d)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }, { kind: "component", type: PropertyValueDisplayComponent, selector: "mm-property-value-display", inputs: ["value", "type", "displayMode", "attributeName"], outputs: ["binaryDownload"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
4459
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityCardWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4460
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EntityCardWidgetComponent, isStandalone: true, selector: "mm-entity-card-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"entity-card\" [class.no-data]=\"!data()\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>Loading...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else if (data()) {\n <!-- Header (like UML class name) -->\n @if (config.showHeader !== false) {\n <div class=\"entity-header\">\n <span class=\"entity-stereotype\">&laquo;{{ entityTypeName() }}&raquo;</span>\n <span class=\"entity-name\">{{ displayName() }}</span>\n </div>\n }\n\n <!-- Attributes Section (like UML attributes) -->\n @if (config.showAttributes !== false && filteredAttributes().length > 0) {\n <div class=\"entity-attributes\">\n @for (attr of filteredAttributes(); track attr.attributeName) {\n <div class=\"attribute-row\">\n <span class=\"attribute-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"attribute-value\">\n <mm-property-value-display\n [value]=\"attr.value\"\n [type]=\"inferAttributeType(attr.value)\"\n [attributeName]=\"attr.attributeName\">\n </mm-property-value-display>\n </span>\n </div>\n }\n </div>\n }\n\n <!-- Metadata Footer -->\n <div class=\"entity-footer\">\n <span class=\"entity-id\" title=\"Runtime ID\">{{ data()!.rtId }}</span>\n </div>\n } @else {\n <div class=\"entity-empty\">\n <span class=\"entity-empty-text\">{{ emptyMessage() }}</span>\n </div>\n }\n</div>\n", styles: [".entity-card{display:flex;flex-direction:column;height:100%;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;overflow:hidden;background:var(--kendo-color-surface, #fff)}.entity-card.no-data,.entity-card.loading,.entity-card.error{justify-content:center;align-items:center}.entity-card.loading{color:var(--kendo-color-primary, #0d6efd)}.entity-card.error{color:var(--kendo-color-error, #dc3545)}.loading-indicator{font-size:.875rem;font-style:italic}.error-message{font-size:.875rem;padding:12px;text-align:center}.entity-header{display:flex;flex-direction:column;align-items:center;padding:12px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);text-align:center}.entity-header .entity-stereotype{font-size:.75rem;font-style:italic;opacity:.9;margin-bottom:2px}.entity-header .entity-name{font-size:1rem;font-weight:600}.entity-attributes{flex:1;padding:8px 0;overflow-y:auto}.entity-attributes .attribute-row{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;border-bottom:1px solid var(--kendo-color-border-alt, #e9ecef);font-size:.8125rem}.entity-attributes .attribute-row:last-child{border-bottom:none}.entity-attributes .attribute-row:hover{background:var(--kendo-color-surface-alt, #f8f9fa)}.entity-attributes .attribute-name{color:var(--kendo-color-subtle, #6c757d);flex-shrink:0;margin-right:12px}.entity-attributes .attribute-value{color:var(--kendo-color-on-surface, #212529);font-weight:500;text-align:right;word-break:break-word;min-width:0;flex:1}.entity-footer{padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-top:1px solid var(--kendo-color-border, #dee2e6)}.entity-footer .entity-id{font-size:.6875rem;font-family:monospace;color:var(--kendo-color-subtle, #6c757d)}.no-data-message{font-size:.875rem}.entity-empty{display:flex;align-items:center;justify-content:center;height:100%;padding:8px;text-align:center}.entity-empty-text{font-size:.875rem;color:var(--kendo-color-subtle, #6c757d)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }, { kind: "component", type: PropertyValueDisplayComponent, selector: "mm-property-value-display", inputs: ["value", "type", "displayMode", "attributeName"], outputs: ["binaryDownload"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
4303
4461
  }
4304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntityCardWidgetComponent, decorators: [{
4462
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityCardWidgetComponent, decorators: [{
4305
4463
  type: Component,
4306
4464
  args: [{ selector: 'mm-entity-card-widget', standalone: true, imports: [CommonModule, WidgetNotConfiguredComponent, PropertyValueDisplayComponent], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"entity-card\" [class.no-data]=\"!data()\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>Loading...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else if (data()) {\n <!-- Header (like UML class name) -->\n @if (config.showHeader !== false) {\n <div class=\"entity-header\">\n <span class=\"entity-stereotype\">&laquo;{{ entityTypeName() }}&raquo;</span>\n <span class=\"entity-name\">{{ displayName() }}</span>\n </div>\n }\n\n <!-- Attributes Section (like UML attributes) -->\n @if (config.showAttributes !== false && filteredAttributes().length > 0) {\n <div class=\"entity-attributes\">\n @for (attr of filteredAttributes(); track attr.attributeName) {\n <div class=\"attribute-row\">\n <span class=\"attribute-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"attribute-value\">\n <mm-property-value-display\n [value]=\"attr.value\"\n [type]=\"inferAttributeType(attr.value)\"\n [attributeName]=\"attr.attributeName\">\n </mm-property-value-display>\n </span>\n </div>\n }\n </div>\n }\n\n <!-- Metadata Footer -->\n <div class=\"entity-footer\">\n <span class=\"entity-id\" title=\"Runtime ID\">{{ data()!.rtId }}</span>\n </div>\n } @else {\n <div class=\"entity-empty\">\n <span class=\"entity-empty-text\">{{ emptyMessage() }}</span>\n </div>\n }\n</div>\n", styles: [".entity-card{display:flex;flex-direction:column;height:100%;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;overflow:hidden;background:var(--kendo-color-surface, #fff)}.entity-card.no-data,.entity-card.loading,.entity-card.error{justify-content:center;align-items:center}.entity-card.loading{color:var(--kendo-color-primary, #0d6efd)}.entity-card.error{color:var(--kendo-color-error, #dc3545)}.loading-indicator{font-size:.875rem;font-style:italic}.error-message{font-size:.875rem;padding:12px;text-align:center}.entity-header{display:flex;flex-direction:column;align-items:center;padding:12px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);text-align:center}.entity-header .entity-stereotype{font-size:.75rem;font-style:italic;opacity:.9;margin-bottom:2px}.entity-header .entity-name{font-size:1rem;font-weight:600}.entity-attributes{flex:1;padding:8px 0;overflow-y:auto}.entity-attributes .attribute-row{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;border-bottom:1px solid var(--kendo-color-border-alt, #e9ecef);font-size:.8125rem}.entity-attributes .attribute-row:last-child{border-bottom:none}.entity-attributes .attribute-row:hover{background:var(--kendo-color-surface-alt, #f8f9fa)}.entity-attributes .attribute-name{color:var(--kendo-color-subtle, #6c757d);flex-shrink:0;margin-right:12px}.entity-attributes .attribute-value{color:var(--kendo-color-on-surface, #212529);font-weight:500;text-align:right;word-break:break-word;min-width:0;flex:1}.entity-footer{padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-top:1px solid var(--kendo-color-border, #dee2e6)}.entity-footer .entity-id{font-size:.6875rem;font-family:monospace;color:var(--kendo-color-subtle, #6c757d)}.no-data-message{font-size:.875rem}.entity-empty{display:flex;align-items:center;justify-content:center;height:100%;padding:8px;text-align:center}.entity-empty-text{font-size:.875rem;color:var(--kendo-color-subtle, #6c757d)}\n"] }]
4307
4465
  }], propDecorators: { config: [{
@@ -4324,14 +4482,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
4324
4482
  */
4325
4483
  class LoadingOverlayComponent {
4326
4484
  loading = false;
4327
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: LoadingOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4328
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: LoadingOverlayComponent, isStandalone: true, selector: "mm-loading-overlay", inputs: { loading: "loading" }, host: { properties: { "class.active": "loading" } }, ngImport: i0, template: `
4485
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LoadingOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4486
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: LoadingOverlayComponent, isStandalone: true, selector: "mm-loading-overlay", inputs: { loading: "loading" }, host: { properties: { "class.active": "loading" } }, ngImport: i0, template: `
4329
4487
  @if (loading) {
4330
4488
  <kendo-loader type="pulsing" size="medium"></kendo-loader>
4331
4489
  }
4332
4490
  `, isInline: true, styles: [":host{display:none}:host.active{display:flex;position:absolute;inset:0;align-items:center;justify-content:center;z-index:100;background:var(--kendo-color-surface-alt, #f8f9fa)}\n"], dependencies: [{ kind: "ngmodule", type: LoaderModule }, { kind: "component", type: i1$2.LoaderComponent, selector: "kendo-loader", inputs: ["type", "themeColor", "size"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
4333
4491
  }
4334
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: LoadingOverlayComponent, decorators: [{
4492
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LoadingOverlayComponent, decorators: [{
4335
4493
  type: Component,
4336
4494
  args: [{ selector: 'mm-loading-overlay', standalone: true, imports: [LoaderModule], host: {
4337
4495
  '[class.active]': 'loading',
@@ -4511,8 +4669,8 @@ class EntityCardConfigDialogComponent {
4511
4669
  onCancel() {
4512
4670
  this.windowRef.close();
4513
4671
  }
4514
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntityCardConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4515
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: EntityCardConfigDialogComponent, isStandalone: true, selector: "mm-entity-card-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialRtId: "initialRtId", initialEntitySelectorId: "initialEntitySelectorId", initialHideEmptyAttributes: "initialHideEmptyAttributes" }, viewQueries: [{ propertyName: "ckTypeSelectorInput", first: true, predicate: ["ckTypeSelector"], descendants: true }, { propertyName: "entitySelectorInput", first: true, predicate: ["entitySelector"], descendants: true }], ngImport: i0, template: `
4672
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityCardConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4673
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EntityCardConfigDialogComponent, isStandalone: true, selector: "mm-entity-card-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialRtId: "initialRtId", initialEntitySelectorId: "initialEntitySelectorId", initialHideEmptyAttributes: "initialHideEmptyAttributes" }, viewQueries: [{ propertyName: "ckTypeSelectorInput", first: true, predicate: ["ckTypeSelector"], descendants: true }, { propertyName: "entitySelectorInput", first: true, predicate: ["entitySelector"], descendants: true }], ngImport: i0, template: `
4516
4674
  <div class="config-container">
4517
4675
 
4518
4676
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -4651,7 +4809,7 @@ class EntityCardConfigDialogComponent {
4651
4809
  </div>
4652
4810
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.config-form{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:20px;padding:16px;position:relative}.config-form.loading{pointer-events:none}.form-field{display:flex;flex-direction:column;gap:6px}.form-field.disabled{opacity:.6}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.selection-preview{padding:12px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.selection-preview h4{margin:0 0 8px;font-size:.9rem;color:var(--kendo-color-primary, #0d6efd)}.preview-content p{margin:4px 0;font-size:.85rem}.checkbox-row{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.checkbox-row input{margin:0}.k-radio-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}.radio-label{margin-left:8px;font-size:.9rem}.field-hint code{font-size:.78rem}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "directive", type: i3.RadioButtonDirective, selector: "input[kendoRadioButton]", inputs: ["size"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
4653
4811
  }
4654
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntityCardConfigDialogComponent, decorators: [{
4812
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityCardConfigDialogComponent, decorators: [{
4655
4813
  type: Component,
4656
4814
  args: [{ selector: 'mm-entity-card-config-dialog', standalone: true, imports: [
4657
4815
  CommonModule,
@@ -5116,6 +5274,20 @@ function processPieChartData(rows, categoryField, valueField) {
5116
5274
  }
5117
5275
  return result;
5118
5276
  }
5277
+ /**
5278
+ * Applies an optional scale factor to a query value (KPI `valueMultiplier`).
5279
+ * Only numeric values are scaled — strings (e.g. enum labels or error
5280
+ * placeholders) pass through unchanged, as does everything when no multiplier
5281
+ * is configured. Use case: cumulated energy from uniformly sampled power
5282
+ * (Σ(kW samples) × sampleIntervalHours → kWh); the factor is window-independent
5283
+ * because SUM is linear in the sample count.
5284
+ */
5285
+ function applyValueMultiplier(value, multiplier) {
5286
+ if (typeof multiplier !== 'number' || typeof value !== 'number') {
5287
+ return value;
5288
+ }
5289
+ return value * multiplier;
5290
+ }
5119
5291
 
5120
5292
  class KpiWidgetComponent {
5121
5293
  dataService = inject(DashboardDataService);
@@ -5416,6 +5588,9 @@ class KpiWidgetComponent {
5416
5588
  value = this.extractGroupedAggregationValue(result);
5417
5589
  break;
5418
5590
  }
5591
+ // Optional scale factor (e.g. Σ(kW samples) × sampleInterval → kWh).
5592
+ // Applied to numeric values only; strings pass through unchanged.
5593
+ value = applyValueMultiplier(value, this.config.valueMultiplier);
5419
5594
  // Create a synthetic entity with the value
5420
5595
  const kpiEntity = {
5421
5596
  rtId: 'query-entity',
@@ -5506,10 +5681,10 @@ class KpiWidgetComponent {
5506
5681
  const variables = this.stateService.getVariables();
5507
5682
  return this.variableService.convertToFieldFilterDto(filters, variables);
5508
5683
  }
5509
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: KpiWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5510
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: KpiWidgetComponent, isStandalone: true, selector: "mm-kpi-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"kpi-widget\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else {\n <div class=\"kpi-content\">\n <div class=\"kpi-value-container\">\n @if (config.prefix) {\n <span class=\"kpi-prefix\">{{ config.prefix }}</span>\n }\n <span class=\"kpi-value\">{{ value() }}</span>\n @if (config.suffix) {\n <span class=\"kpi-suffix\">{{ config.suffix }}</span>\n }\n </div>\n\n @if (comparisonText()) {\n <div class=\"kpi-comparison\" [ngClass]=\"trendClass()\">\n @if (config.trend) {\n <kendo-svg-icon [icon]=\"trendIcon()\" size=\"xsmall\"></kendo-svg-icon>\n }\n {{ comparisonText() }}\n </div>\n }\n\n @if (label()) {\n <div class=\"kpi-label\">{{ label() }}</div>\n }\n </div>\n\n @if (config.trend) {\n <div class=\"kpi-trend\" [ngClass]=\"trendClass()\">\n <kendo-svg-icon [icon]=\"trendIcon()\" size=\"medium\"></kendo-svg-icon>\n </div>\n }\n }\n</div>\n", styles: [".kpi-widget{display:flex;align-items:center;justify-content:center;height:100%;padding:16px;gap:16px}.kpi-content{display:flex;flex-direction:column;align-items:center;text-align:center}.kpi-value-container{display:flex;align-items:baseline;gap:4px}.kpi-prefix,.kpi-suffix{font-size:1.25rem;font-weight:500;color:var(--kendo-color-subtle, #6c757d)}.kpi-value{font-size:2.5rem;font-weight:700;color:var(--kendo-color-on-surface, #212529);line-height:1}.kpi-comparison{margin-top:4px;font-size:.75rem;font-weight:500;display:flex;align-items:center;gap:4px;justify-content:center}.kpi-comparison.trend-up{color:var(--kendo-color-success, #28a745)}.kpi-comparison.trend-down{color:var(--kendo-color-error, #dc3545)}.kpi-comparison.trend-neutral{color:var(--kendo-color-subtle, #6c757d)}.kpi-label{margin-top:8px;font-size:.875rem;color:var(--kendo-color-subtle, #6c757d)}.kpi-trend{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%}.kpi-trend.trend-up{background:#28a74526;color:var(--kendo-color-success, #28a745)}.kpi-trend.trend-down{background:#dc354526;color:var(--kendo-color-error, #dc3545)}.kpi-trend.trend-neutral{background:#6c757d26;color:var(--kendo-color-subtle, #6c757d)}@media(max-width:768px){.kpi-value{font-size:1.75rem}.kpi-prefix,.kpi-suffix{font-size:1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
5684
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KpiWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5685
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KpiWidgetComponent, isStandalone: true, selector: "mm-kpi-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"kpi-widget\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else {\n <div class=\"kpi-content\">\n <div class=\"kpi-value-container\">\n @if (config.prefix) {\n <span class=\"kpi-prefix\">{{ config.prefix }}</span>\n }\n <span class=\"kpi-value\">{{ value() }}</span>\n @if (config.suffix) {\n <span class=\"kpi-suffix\">{{ config.suffix }}</span>\n }\n </div>\n\n @if (comparisonText()) {\n <div class=\"kpi-comparison\" [ngClass]=\"trendClass()\">\n @if (config.trend) {\n <kendo-svg-icon [icon]=\"trendIcon()\" size=\"xsmall\"></kendo-svg-icon>\n }\n {{ comparisonText() }}\n </div>\n }\n\n @if (label()) {\n <div class=\"kpi-label\">{{ label() }}</div>\n }\n </div>\n\n @if (config.trend) {\n <div class=\"kpi-trend\" [ngClass]=\"trendClass()\">\n <kendo-svg-icon [icon]=\"trendIcon()\" size=\"medium\"></kendo-svg-icon>\n </div>\n }\n }\n</div>\n", styles: [".kpi-widget{display:flex;align-items:center;justify-content:center;height:100%;padding:16px;gap:16px}.kpi-content{display:flex;flex-direction:column;align-items:center;text-align:center}.kpi-value-container{display:flex;align-items:baseline;gap:4px}.kpi-prefix,.kpi-suffix{font-size:1.25rem;font-weight:500;color:var(--kendo-color-subtle, #6c757d)}.kpi-value{font-size:2.5rem;font-weight:700;color:var(--kendo-color-on-surface, #212529);line-height:1}.kpi-comparison{margin-top:4px;font-size:.75rem;font-weight:500;display:flex;align-items:center;gap:4px;justify-content:center}.kpi-comparison.trend-up{color:var(--kendo-color-success, #28a745)}.kpi-comparison.trend-down{color:var(--kendo-color-error, #dc3545)}.kpi-comparison.trend-neutral{color:var(--kendo-color-subtle, #6c757d)}.kpi-label{margin-top:8px;font-size:.875rem;color:var(--kendo-color-subtle, #6c757d)}.kpi-trend{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%}.kpi-trend.trend-up{background:#28a74526;color:var(--kendo-color-success, #28a745)}.kpi-trend.trend-down{background:#dc354526;color:var(--kendo-color-error, #dc3545)}.kpi-trend.trend-neutral{background:#6c757d26;color:var(--kendo-color-subtle, #6c757d)}@media(max-width:768px){.kpi-value{font-size:1.75rem}.kpi-prefix,.kpi-suffix{font-size:1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
5511
5686
  }
5512
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: KpiWidgetComponent, decorators: [{
5687
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KpiWidgetComponent, decorators: [{
5513
5688
  type: Component,
5514
5689
  args: [{ selector: 'mm-kpi-widget', standalone: true, imports: [CommonModule, SVGIconModule, WidgetNotConfiguredComponent], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"kpi-widget\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else {\n <div class=\"kpi-content\">\n <div class=\"kpi-value-container\">\n @if (config.prefix) {\n <span class=\"kpi-prefix\">{{ config.prefix }}</span>\n }\n <span class=\"kpi-value\">{{ value() }}</span>\n @if (config.suffix) {\n <span class=\"kpi-suffix\">{{ config.suffix }}</span>\n }\n </div>\n\n @if (comparisonText()) {\n <div class=\"kpi-comparison\" [ngClass]=\"trendClass()\">\n @if (config.trend) {\n <kendo-svg-icon [icon]=\"trendIcon()\" size=\"xsmall\"></kendo-svg-icon>\n }\n {{ comparisonText() }}\n </div>\n }\n\n @if (label()) {\n <div class=\"kpi-label\">{{ label() }}</div>\n }\n </div>\n\n @if (config.trend) {\n <div class=\"kpi-trend\" [ngClass]=\"trendClass()\">\n <kendo-svg-icon [icon]=\"trendIcon()\" size=\"medium\"></kendo-svg-icon>\n </div>\n }\n }\n</div>\n", styles: [".kpi-widget{display:flex;align-items:center;justify-content:center;height:100%;padding:16px;gap:16px}.kpi-content{display:flex;flex-direction:column;align-items:center;text-align:center}.kpi-value-container{display:flex;align-items:baseline;gap:4px}.kpi-prefix,.kpi-suffix{font-size:1.25rem;font-weight:500;color:var(--kendo-color-subtle, #6c757d)}.kpi-value{font-size:2.5rem;font-weight:700;color:var(--kendo-color-on-surface, #212529);line-height:1}.kpi-comparison{margin-top:4px;font-size:.75rem;font-weight:500;display:flex;align-items:center;gap:4px;justify-content:center}.kpi-comparison.trend-up{color:var(--kendo-color-success, #28a745)}.kpi-comparison.trend-down{color:var(--kendo-color-error, #dc3545)}.kpi-comparison.trend-neutral{color:var(--kendo-color-subtle, #6c757d)}.kpi-label{margin-top:8px;font-size:.875rem;color:var(--kendo-color-subtle, #6c757d)}.kpi-trend{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%}.kpi-trend.trend-up{background:#28a74526;color:var(--kendo-color-success, #28a745)}.kpi-trend.trend-down{background:#dc354526;color:var(--kendo-color-error, #dc3545)}.kpi-trend.trend-neutral{background:#6c757d26;color:var(--kendo-color-subtle, #6c757d)}@media(max-width:768px){.kpi-value{font-size:1.75rem}.kpi-prefix,.kpi-suffix{font-size:1rem}}\n"] }]
5515
5690
  }], propDecorators: { config: [{
@@ -5538,10 +5713,10 @@ class GetRuntimeQueryColumnsDtoGQL extends i1.Query {
5538
5713
  constructor(apollo) {
5539
5714
  super(apollo);
5540
5715
  }
5541
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetRuntimeQueryColumnsDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
5542
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetRuntimeQueryColumnsDtoGQL, providedIn: 'root' });
5716
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetRuntimeQueryColumnsDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
5717
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetRuntimeQueryColumnsDtoGQL, providedIn: 'root' });
5543
5718
  }
5544
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetRuntimeQueryColumnsDtoGQL, decorators: [{
5719
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetRuntimeQueryColumnsDtoGQL, decorators: [{
5545
5720
  type: Injectable,
5546
5721
  args: [{
5547
5722
  providedIn: 'root'
@@ -5582,8 +5757,8 @@ class SdTimeFilterToggleComponent {
5582
5757
  this.ignoreTimeFilter = value;
5583
5758
  this.ignoreTimeFilterChange.emit(value);
5584
5759
  }
5585
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SdTimeFilterToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5586
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: SdTimeFilterToggleComponent, isStandalone: true, selector: "mm-sd-time-filter-toggle", inputs: { family: "family", ignoreTimeFilter: "ignoreTimeFilter" }, outputs: { ignoreTimeFilterChange: "ignoreTimeFilterChange" }, ngImport: i0, template: `
5760
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SdTimeFilterToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5761
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: SdTimeFilterToggleComponent, isStandalone: true, selector: "mm-sd-time-filter-toggle", inputs: { family: "family", ignoreTimeFilter: "ignoreTimeFilter" }, outputs: { ignoreTimeFilterChange: "ignoreTimeFilterChange" }, ngImport: i0, template: `
5587
5762
  @if (visible) {
5588
5763
  <div class="form-field sd-time-filter-toggle">
5589
5764
  <label class="checkbox-label">
@@ -5602,7 +5777,7 @@ class SdTimeFilterToggleComponent {
5602
5777
  }
5603
5778
  `, isInline: true, styles: [".sd-time-filter-toggle .checkbox-label{display:flex;align-items:center;gap:8px;cursor:pointer}.sd-time-filter-toggle .field-hint{font-size:.85em;margin-top:4px;opacity:.7}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputsModule }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
5604
5779
  }
5605
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SdTimeFilterToggleComponent, decorators: [{
5780
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SdTimeFilterToggleComponent, decorators: [{
5606
5781
  type: Component,
5607
5782
  args: [{ selector: 'mm-sd-time-filter-toggle', standalone: true, imports: [FormsModule, InputsModule], changeDetection: ChangeDetectionStrategy.Eager, template: `
5608
5783
  @if (visible) {
@@ -5683,8 +5858,8 @@ class EntitySelectorScopePickerComponent {
5683
5858
  this.entitySelectorId = value ?? undefined;
5684
5859
  this.entitySelectorIdChange.emit(this.entitySelectorId);
5685
5860
  }
5686
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntitySelectorScopePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5687
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: EntitySelectorScopePickerComponent, isStandalone: true, selector: "mm-entity-selector-scope-picker", inputs: { family: "family", entitySelectorId: "entitySelectorId", selectors: "selectors" }, outputs: { entitySelectorIdChange: "entitySelectorIdChange" }, ngImport: i0, template: `
5861
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntitySelectorScopePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5862
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EntitySelectorScopePickerComponent, isStandalone: true, selector: "mm-entity-selector-scope-picker", inputs: { family: "family", entitySelectorId: "entitySelectorId", selectors: "selectors" }, outputs: { entitySelectorIdChange: "entitySelectorIdChange" }, ngImport: i0, template: `
5688
5863
  @if (visible) {
5689
5864
  <div class="form-field entity-selector-scope-picker">
5690
5865
  <label>Scope to entity selector</label>
@@ -5704,7 +5879,7 @@ class EntitySelectorScopePickerComponent {
5704
5879
  }
5705
5880
  `, isInline: true, styles: [".entity-selector-scope-picker .field-hint{font-size:.85em;margin-top:4px;opacity:.7}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
5706
5881
  }
5707
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntitySelectorScopePickerComponent, decorators: [{
5882
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntitySelectorScopePickerComponent, decorators: [{
5708
5883
  type: Component,
5709
5884
  args: [{ selector: 'mm-entity-selector-scope-picker', standalone: true, imports: [FormsModule, DropDownsModule], changeDetection: ChangeDetectionStrategy.Eager, template: `
5710
5885
  @if (visible) {
@@ -6240,8 +6415,8 @@ class KpiConfigDialogComponent {
6240
6415
  onFiltersChange(updatedFilters) {
6241
6416
  this.filters = updatedFilters;
6242
6417
  }
6243
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: KpiConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6244
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: KpiConfigDialogComponent, isStandalone: true, selector: "mm-kpi-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialRtId: "initialRtId", initialValueAttribute: "initialValueAttribute", initialLabelAttribute: "initialLabelAttribute", initialPrefix: "initialPrefix", initialSuffix: "initialSuffix", initialTrend: "initialTrend", initialComparisonText: "initialComparisonText", initialDataSourceType: "initialDataSourceType", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialQueryMode: "initialQueryMode", initialQueryValueField: "initialQueryValueField", initialQueryCategoryField: "initialQueryCategoryField", initialQueryCategoryValue: "initialQueryCategoryValue", initialStaticValue: "initialStaticValue", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "ckTypeSelectorInput", first: true, predicate: ["ckTypeSelector"], descendants: true }, { propertyName: "entitySelectorInput", first: true, predicate: ["entitySelector"], descendants: true }, { propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
6418
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KpiConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6419
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KpiConfigDialogComponent, isStandalone: true, selector: "mm-kpi-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialRtId: "initialRtId", initialValueAttribute: "initialValueAttribute", initialLabelAttribute: "initialLabelAttribute", initialPrefix: "initialPrefix", initialSuffix: "initialSuffix", initialTrend: "initialTrend", initialComparisonText: "initialComparisonText", initialDataSourceType: "initialDataSourceType", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialQueryMode: "initialQueryMode", initialQueryValueField: "initialQueryValueField", initialQueryCategoryField: "initialQueryCategoryField", initialQueryCategoryValue: "initialQueryCategoryValue", initialStaticValue: "initialStaticValue", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "ckTypeSelectorInput", first: true, predicate: ["ckTypeSelector"], descendants: true }, { propertyName: "entitySelectorInput", first: true, predicate: ["entitySelector"], descendants: true }, { propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
6245
6420
  <div class="config-container">
6246
6421
 
6247
6422
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -6625,7 +6800,7 @@ class KpiConfigDialogComponent {
6625
6800
  </div>
6626
6801
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:20px;flex:1;overflow-y:auto;padding:16px;position:relative}.config-form.loading{pointer-events:none}.form-field{display:flex;flex-direction:column;gap:6px}.form-field.disabled{opacity:.6}.form-field.flex-1{flex:1}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.form-section h4{margin:0 0 16px;font-size:.95rem;color:var(--kendo-color-primary, #0d6efd)}.section-hint{margin:0 0 12px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.form-row{display:flex;gap:16px}.mode-toggle{display:flex;gap:8px}.mode-toggle button{flex:1}.attribute-item{display:flex;justify-content:space-between;align-items:center;gap:8px;width:100%}.attribute-path{flex:1}.attribute-type{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);background:var(--kendo-color-surface-alt, #f8f9fa);padding:2px 6px;border-radius:3px}.required{color:var(--kendo-color-error, #dc3545)}.query-item{display:flex;flex-direction:column;gap:2px}.query-name{font-weight:500}.query-description{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.column-item{display:flex;justify-content:space-between;gap:16px}.column-path{font-weight:500}.column-type{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: QuerySelectorComponent, selector: "mm-query-selector", inputs: ["placeholder", "hint", "disabled", "acceptFamilies"], outputs: ["querySelected", "queriesLoaded"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
6627
6802
  }
6628
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: KpiConfigDialogComponent, decorators: [{
6803
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KpiConfigDialogComponent, decorators: [{
6629
6804
  type: Component,
6630
6805
  args: [{ selector: 'mm-kpi-config-dialog', standalone: true, imports: [
6631
6806
  CommonModule,
@@ -7195,8 +7370,8 @@ class EntityDetailDialogComponent {
7195
7370
  onClose() {
7196
7371
  this.closed.emit();
7197
7372
  }
7198
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntityDetailDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7199
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: EntityDetailDialogComponent, isStandalone: true, selector: "mm-entity-detail-dialog", inputs: { rtId: "rtId", ckTypeId: "ckTypeId" }, outputs: { closed: "closed" }, ngImport: i0, template: `
7373
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityDetailDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7374
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EntityDetailDialogComponent, isStandalone: true, selector: "mm-entity-detail-dialog", inputs: { rtId: "rtId", ckTypeId: "ckTypeId" }, outputs: { closed: "closed" }, ngImport: i0, template: `
7200
7375
  <kendo-dialog
7201
7376
  [title]="dialogTitle"
7202
7377
  [minWidth]="600"
@@ -7245,7 +7420,7 @@ class EntityDetailDialogComponent {
7245
7420
  </kendo-dialog>
7246
7421
  `, isInline: true, styles: [".entity-detail-content{display:flex;flex-direction:column;gap:16px;min-height:400px}.loading-indicator,.error-message{display:flex;align-items:center;justify-content:center;height:200px;color:var(--kendo-color-subtle, #6c757d)}.error-message{color:var(--kendo-color-error, #dc3545)}.entity-header{padding:12px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.entity-info{display:flex;flex-direction:column;gap:6px}.info-row{display:flex;gap:8px;font-size:.875rem}.info-row .label{font-weight:600;color:var(--kendo-color-subtle, #6c757d);min-width:80px}.info-row .value{color:var(--kendo-color-on-surface, #212529);word-break:break-all}.attributes-section{flex:1;display:flex;flex-direction:column}.attributes-section h4{margin:0 0 8px;font-size:.9rem;color:var(--kendo-color-primary, #0d6efd)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DialogsModule }, { kind: "component", type: i1$5.DialogComponent, selector: "kendo-dialog", inputs: ["actions", "actionsLayout", "autoFocusedElement", "closable", "title", "width", "minWidth", "maxWidth", "height", "minHeight", "maxHeight", "animation"], outputs: ["action", "close"], exportAs: ["kendoDialog"] }, { kind: "component", type: i1$5.DialogActionsComponent, selector: "kendo-dialog-actions", inputs: ["actions", "layout"], outputs: ["action"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: PropertyGridComponent, selector: "mm-property-grid", inputs: ["data", "config", "showTypeColumn", "messages"], outputs: ["propertyChange", "saveRequested", "binaryDownload"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
7247
7422
  }
7248
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntityDetailDialogComponent, decorators: [{
7423
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityDetailDialogComponent, decorators: [{
7249
7424
  type: Component,
7250
7425
  args: [{ selector: 'mm-entity-detail-dialog', standalone: true, imports: [
7251
7426
  CommonModule,
@@ -7339,9 +7514,18 @@ function toInstant(value) {
7339
7514
  }
7340
7515
  return null;
7341
7516
  }
7342
- /** Maps the board mode to the `Intl` `timeZone` option (`undefined` = browser local). */
7517
+ /**
7518
+ * Maps the board mode to the `Intl` `timeZone` option (`undefined` = browser local).
7519
+ * An IANA id (AB#4190) is passed straight through to `Intl`, which already resolves it.
7520
+ */
7343
7521
  function timeZoneOption(mode) {
7344
- return mode === 'utc' ? 'UTC' : undefined;
7522
+ if (mode === 'utc') {
7523
+ return 'UTC';
7524
+ }
7525
+ if (mode === 'local') {
7526
+ return undefined;
7527
+ }
7528
+ return mode;
7345
7529
  }
7346
7530
  /**
7347
7531
  * Cached `Intl.DateTimeFormat` per board mode. Bucketing widgets call
@@ -7767,10 +7951,10 @@ class EntityAssociationsWidgetComponent {
7767
7951
  .replace(/^./, str => str.toUpperCase())
7768
7952
  .trim();
7769
7953
  }
7770
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntityAssociationsWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7771
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: EntityAssociationsWidgetComponent, isStandalone: true, selector: "mm-entity-associations-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"associations-widget\" [class.no-data]=\"!data()\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>Loading...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else if (data()) {\n <!-- Entity Info Header -->\n <div class=\"entity-header\">\n <div class=\"entity-box\">\n <span class=\"entity-name\">{{ entityName() }}</span>\n </div>\n <div class=\"entity-details\">\n <span class=\"entity-id\" title=\"{{ entityCkTypeId() }}\">{{ entityRtId() }}</span>\n </div>\n </div>\n\n <!-- Entity Attributes (Source) -->\n @if (filteredEntityAttributes().length > 0) {\n <div class=\"entity-attributes\">\n @for (attr of filteredEntityAttributes(); track attr.attributeName) {\n <div class=\"attribute-row\">\n <span class=\"attribute-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"attribute-value\">{{ formatValue(attr.value) }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Associations List -->\n <div class=\"associations-container\">\n @for (group of groupedAssociations(); track group.roleId + group.direction) {\n <div class=\"association-group\" [class.expanded]=\"isGroupExpanded(group)\">\n <!-- Group Header -->\n <div class=\"group-header\"\n [class.clickable]=\"displayMode() === 'expandable'\"\n (click)=\"toggleGroup(group)\">\n <div class=\"direction-indicator\">\n @if (group.direction === 'out') {\n <kendo-svg-icon [icon]=\"arrowRightIcon\" size=\"small\"></kendo-svg-icon>\n } @else {\n <kendo-svg-icon [icon]=\"arrowLeftIcon\" size=\"small\"></kendo-svg-icon>\n }\n </div>\n <div class=\"group-info\">\n <span class=\"role-name\">{{ group.roleName }}</span>\n <span class=\"target-type\">{{ group.targetType }}</span>\n <span class=\"count-badge\">{{ group.count }}</span>\n </div>\n @if (displayMode() === 'expandable') {\n <div class=\"expand-icon\">\n @if (isGroupExpanded(group)) {\n <kendo-svg-icon [icon]=\"chevronDownIcon\" size=\"small\"></kendo-svg-icon>\n } @else {\n <kendo-svg-icon [icon]=\"chevronRightIcon\" size=\"small\"></kendo-svg-icon>\n }\n </div>\n }\n </div>\n\n <!-- Expanded Target List -->\n @if (displayMode() === 'expandable' && isGroupExpanded(group)) {\n <div class=\"target-list\">\n @if (isLoadingTargets(group)) {\n <div class=\"target-loading\">Loading attributes...</div>\n }\n @for (target of getTargetEntities(group); track target.rtId) {\n <div class=\"target-entry\">\n <div class=\"target-item\" (click)=\"onTargetClick(target)\">\n <span class=\"target-id\">{{ target.displayName }}</span>\n <span class=\"target-type-hint\" [title]=\"target.ckTypeId\">{{ target.ckTypeId }}</span>\n </div>\n @if (target.attributes?.length) {\n <div class=\"target-attributes\">\n @for (attr of target.attributes; track attr.attributeName) {\n <div class=\"target-attr-row\">\n <span class=\"target-attr-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"target-attr-value\">{{ formatValue(attr.value) }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Summary Footer -->\n <div class=\"associations-summary\">\n <kendo-svg-icon [icon]=\"linkIcon\" size=\"small\"></kendo-svg-icon>\n <span>{{ totalAssociations() }} relationship(s)</span>\n </div>\n } @else {\n <mm-widget-not-configured></mm-widget-not-configured>\n }\n</div>\n\n<!-- Entity Detail Dialog -->\n@if (showDetailDialog) {\n <mm-entity-detail-dialog\n [rtId]=\"detailEntityRtId\"\n [ckTypeId]=\"detailEntityCkTypeId\"\n (closed)=\"onDetailDialogClosed()\">\n </mm-entity-detail-dialog>\n}\n", styles: [".associations-widget{display:flex;flex-direction:column;height:100%}.associations-widget.no-data{justify-content:center;align-items:center;color:var(--kendo-color-subtle, #6c757d)}.entity-header{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.entity-header .entity-box{display:flex;align-items:center;justify-content:center;padding:8px 16px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);border-radius:4px;font-weight:600;font-size:.875rem}.entity-header .entity-details{display:flex;flex-direction:column;gap:2px}.entity-header .entity-id{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);font-family:monospace}.entity-attributes{padding:4px 12px 8px;border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.entity-attributes .attribute-row{display:flex;justify-content:space-between;padding:2px 0;font-size:.8125rem}.entity-attributes .attribute-name{color:var(--kendo-color-subtle, #6c757d)}.entity-attributes .attribute-value{font-weight:500;color:var(--kendo-color-on-surface, #212529)}.associations-container{flex:1;overflow:auto;padding:8px;display:flex;flex-direction:column;gap:4px}.association-group{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;overflow:hidden}.association-group.expanded .group-header{border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.group-header{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa)}.group-header.clickable{cursor:pointer}.group-header.clickable:hover{background:var(--kendo-color-surface, #ffffff)}.direction-indicator{color:var(--kendo-color-subtle, #6c757d);display:flex;align-items:center;width:20px}.group-info{display:flex;align-items:center;gap:8px;flex:1;font-size:.8125rem}.group-info .role-name{color:var(--kendo-color-subtle, #6c757d);font-style:italic}.group-info .target-type{font-weight:500;color:var(--kendo-color-on-surface, #212529)}.group-info .count-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);border-radius:10px;font-size:.6875rem;font-weight:600}.expand-icon{color:var(--kendo-color-subtle, #6c757d);display:flex;align-items:center}.target-list{padding:4px 0;max-height:200px;overflow-y:auto}.target-entry+.target-entry{border-top:1px solid var(--kendo-color-border, #dee2e6)}.target-item{display:flex;align-items:center;gap:8px;padding:6px 12px 6px 40px;cursor:pointer;font-size:.8125rem;transition:background .15s ease}.target-item:hover{background:var(--kendo-color-surface-alt, #f8f9fa)}.target-item .target-id{font-family:monospace;color:var(--kendo-color-on-surface, #212529);flex-shrink:0}.target-item .target-type-hint{font-size:.6875rem;color:var(--kendo-color-subtle, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex-shrink:1}.target-attributes{padding:2px 12px 6px 56px}.target-attributes .target-attr-row{display:flex;justify-content:space-between;padding:1px 0;font-size:.75rem}.target-attributes .target-attr-name{color:var(--kendo-color-subtle, #6c757d)}.target-attributes .target-attr-value{color:var(--kendo-color-on-surface, #212529);font-weight:500}.target-loading{padding:6px 12px 6px 40px;font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.associations-summary{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-top:1px solid var(--kendo-color-border, #dee2e6);font-size:.75rem;color:var(--kendo-color-subtle, #6c757d)}.no-data-message{font-size:.875rem}.loading-indicator{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-subtle, #6c757d)}.error-message{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: EntityDetailDialogComponent, selector: "mm-entity-detail-dialog", inputs: ["rtId", "ckTypeId"], outputs: ["closed"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
7954
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityAssociationsWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7955
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EntityAssociationsWidgetComponent, isStandalone: true, selector: "mm-entity-associations-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"associations-widget\" [class.no-data]=\"!data()\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>Loading...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else if (data()) {\n <!-- Entity Info Header -->\n <div class=\"entity-header\">\n <div class=\"entity-box\">\n <span class=\"entity-name\">{{ entityName() }}</span>\n </div>\n <div class=\"entity-details\">\n <span class=\"entity-id\" title=\"{{ entityCkTypeId() }}\">{{ entityRtId() }}</span>\n </div>\n </div>\n\n <!-- Entity Attributes (Source) -->\n @if (filteredEntityAttributes().length > 0) {\n <div class=\"entity-attributes\">\n @for (attr of filteredEntityAttributes(); track attr.attributeName) {\n <div class=\"attribute-row\">\n <span class=\"attribute-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"attribute-value\">{{ formatValue(attr.value) }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Associations List -->\n <div class=\"associations-container\">\n @for (group of groupedAssociations(); track group.roleId + group.direction) {\n <div class=\"association-group\" [class.expanded]=\"isGroupExpanded(group)\">\n <!-- Group Header -->\n <div class=\"group-header\"\n [class.clickable]=\"displayMode() === 'expandable'\"\n (click)=\"toggleGroup(group)\">\n <div class=\"direction-indicator\">\n @if (group.direction === 'out') {\n <kendo-svg-icon [icon]=\"arrowRightIcon\" size=\"small\"></kendo-svg-icon>\n } @else {\n <kendo-svg-icon [icon]=\"arrowLeftIcon\" size=\"small\"></kendo-svg-icon>\n }\n </div>\n <div class=\"group-info\">\n <span class=\"role-name\">{{ group.roleName }}</span>\n <span class=\"target-type\">{{ group.targetType }}</span>\n <span class=\"count-badge\">{{ group.count }}</span>\n </div>\n @if (displayMode() === 'expandable') {\n <div class=\"expand-icon\">\n @if (isGroupExpanded(group)) {\n <kendo-svg-icon [icon]=\"chevronDownIcon\" size=\"small\"></kendo-svg-icon>\n } @else {\n <kendo-svg-icon [icon]=\"chevronRightIcon\" size=\"small\"></kendo-svg-icon>\n }\n </div>\n }\n </div>\n\n <!-- Expanded Target List -->\n @if (displayMode() === 'expandable' && isGroupExpanded(group)) {\n <div class=\"target-list\">\n @if (isLoadingTargets(group)) {\n <div class=\"target-loading\">Loading attributes...</div>\n }\n @for (target of getTargetEntities(group); track target.rtId) {\n <div class=\"target-entry\">\n <div class=\"target-item\" (click)=\"onTargetClick(target)\">\n <span class=\"target-id\">{{ target.displayName }}</span>\n <span class=\"target-type-hint\" [title]=\"target.ckTypeId\">{{ target.ckTypeId }}</span>\n </div>\n @if (target.attributes?.length) {\n <div class=\"target-attributes\">\n @for (attr of target.attributes; track attr.attributeName) {\n <div class=\"target-attr-row\">\n <span class=\"target-attr-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"target-attr-value\">{{ formatValue(attr.value) }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Summary Footer -->\n <div class=\"associations-summary\">\n <kendo-svg-icon [icon]=\"linkIcon\" size=\"small\"></kendo-svg-icon>\n <span>{{ totalAssociations() }} relationship(s)</span>\n </div>\n } @else {\n <mm-widget-not-configured></mm-widget-not-configured>\n }\n</div>\n\n<!-- Entity Detail Dialog -->\n@if (showDetailDialog) {\n <mm-entity-detail-dialog\n [rtId]=\"detailEntityRtId\"\n [ckTypeId]=\"detailEntityCkTypeId\"\n (closed)=\"onDetailDialogClosed()\">\n </mm-entity-detail-dialog>\n}\n", styles: [".associations-widget{display:flex;flex-direction:column;height:100%}.associations-widget.no-data{justify-content:center;align-items:center;color:var(--kendo-color-subtle, #6c757d)}.entity-header{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.entity-header .entity-box{display:flex;align-items:center;justify-content:center;padding:8px 16px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);border-radius:4px;font-weight:600;font-size:.875rem}.entity-header .entity-details{display:flex;flex-direction:column;gap:2px}.entity-header .entity-id{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);font-family:monospace}.entity-attributes{padding:4px 12px 8px;border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.entity-attributes .attribute-row{display:flex;justify-content:space-between;padding:2px 0;font-size:.8125rem}.entity-attributes .attribute-name{color:var(--kendo-color-subtle, #6c757d)}.entity-attributes .attribute-value{font-weight:500;color:var(--kendo-color-on-surface, #212529)}.associations-container{flex:1;overflow:auto;padding:8px;display:flex;flex-direction:column;gap:4px}.association-group{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;overflow:hidden}.association-group.expanded .group-header{border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.group-header{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa)}.group-header.clickable{cursor:pointer}.group-header.clickable:hover{background:var(--kendo-color-surface, #ffffff)}.direction-indicator{color:var(--kendo-color-subtle, #6c757d);display:flex;align-items:center;width:20px}.group-info{display:flex;align-items:center;gap:8px;flex:1;font-size:.8125rem}.group-info .role-name{color:var(--kendo-color-subtle, #6c757d);font-style:italic}.group-info .target-type{font-weight:500;color:var(--kendo-color-on-surface, #212529)}.group-info .count-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);border-radius:10px;font-size:.6875rem;font-weight:600}.expand-icon{color:var(--kendo-color-subtle, #6c757d);display:flex;align-items:center}.target-list{padding:4px 0;max-height:200px;overflow-y:auto}.target-entry+.target-entry{border-top:1px solid var(--kendo-color-border, #dee2e6)}.target-item{display:flex;align-items:center;gap:8px;padding:6px 12px 6px 40px;cursor:pointer;font-size:.8125rem;transition:background .15s ease}.target-item:hover{background:var(--kendo-color-surface-alt, #f8f9fa)}.target-item .target-id{font-family:monospace;color:var(--kendo-color-on-surface, #212529);flex-shrink:0}.target-item .target-type-hint{font-size:.6875rem;color:var(--kendo-color-subtle, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex-shrink:1}.target-attributes{padding:2px 12px 6px 56px}.target-attributes .target-attr-row{display:flex;justify-content:space-between;padding:1px 0;font-size:.75rem}.target-attributes .target-attr-name{color:var(--kendo-color-subtle, #6c757d)}.target-attributes .target-attr-value{color:var(--kendo-color-on-surface, #212529);font-weight:500}.target-loading{padding:6px 12px 6px 40px;font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.associations-summary{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-top:1px solid var(--kendo-color-border, #dee2e6);font-size:.75rem;color:var(--kendo-color-subtle, #6c757d)}.no-data-message{font-size:.875rem}.loading-indicator{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-subtle, #6c757d)}.error-message{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: EntityDetailDialogComponent, selector: "mm-entity-detail-dialog", inputs: ["rtId", "ckTypeId"], outputs: ["closed"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
7772
7956
  }
7773
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntityAssociationsWidgetComponent, decorators: [{
7957
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityAssociationsWidgetComponent, decorators: [{
7774
7958
  type: Component,
7775
7959
  args: [{ selector: 'mm-entity-associations-widget', standalone: true, imports: [CommonModule, SVGIconModule, EntityDetailDialogComponent, WidgetNotConfiguredComponent], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"associations-widget\" [class.no-data]=\"!data()\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-indicator\">\n <span>Loading...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-message\">\n <span>{{ error() }}</span>\n </div>\n } @else if (data()) {\n <!-- Entity Info Header -->\n <div class=\"entity-header\">\n <div class=\"entity-box\">\n <span class=\"entity-name\">{{ entityName() }}</span>\n </div>\n <div class=\"entity-details\">\n <span class=\"entity-id\" title=\"{{ entityCkTypeId() }}\">{{ entityRtId() }}</span>\n </div>\n </div>\n\n <!-- Entity Attributes (Source) -->\n @if (filteredEntityAttributes().length > 0) {\n <div class=\"entity-attributes\">\n @for (attr of filteredEntityAttributes(); track attr.attributeName) {\n <div class=\"attribute-row\">\n <span class=\"attribute-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"attribute-value\">{{ formatValue(attr.value) }}</span>\n </div>\n }\n </div>\n }\n\n <!-- Associations List -->\n <div class=\"associations-container\">\n @for (group of groupedAssociations(); track group.roleId + group.direction) {\n <div class=\"association-group\" [class.expanded]=\"isGroupExpanded(group)\">\n <!-- Group Header -->\n <div class=\"group-header\"\n [class.clickable]=\"displayMode() === 'expandable'\"\n (click)=\"toggleGroup(group)\">\n <div class=\"direction-indicator\">\n @if (group.direction === 'out') {\n <kendo-svg-icon [icon]=\"arrowRightIcon\" size=\"small\"></kendo-svg-icon>\n } @else {\n <kendo-svg-icon [icon]=\"arrowLeftIcon\" size=\"small\"></kendo-svg-icon>\n }\n </div>\n <div class=\"group-info\">\n <span class=\"role-name\">{{ group.roleName }}</span>\n <span class=\"target-type\">{{ group.targetType }}</span>\n <span class=\"count-badge\">{{ group.count }}</span>\n </div>\n @if (displayMode() === 'expandable') {\n <div class=\"expand-icon\">\n @if (isGroupExpanded(group)) {\n <kendo-svg-icon [icon]=\"chevronDownIcon\" size=\"small\"></kendo-svg-icon>\n } @else {\n <kendo-svg-icon [icon]=\"chevronRightIcon\" size=\"small\"></kendo-svg-icon>\n }\n </div>\n }\n </div>\n\n <!-- Expanded Target List -->\n @if (displayMode() === 'expandable' && isGroupExpanded(group)) {\n <div class=\"target-list\">\n @if (isLoadingTargets(group)) {\n <div class=\"target-loading\">Loading attributes...</div>\n }\n @for (target of getTargetEntities(group); track target.rtId) {\n <div class=\"target-entry\">\n <div class=\"target-item\" (click)=\"onTargetClick(target)\">\n <span class=\"target-id\">{{ target.displayName }}</span>\n <span class=\"target-type-hint\" [title]=\"target.ckTypeId\">{{ target.ckTypeId }}</span>\n </div>\n @if (target.attributes?.length) {\n <div class=\"target-attributes\">\n @for (attr of target.attributes; track attr.attributeName) {\n <div class=\"target-attr-row\">\n <span class=\"target-attr-name\">{{ formatAttributeName(attr.attributeName) }}</span>\n <span class=\"target-attr-value\">{{ formatValue(attr.value) }}</span>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Summary Footer -->\n <div class=\"associations-summary\">\n <kendo-svg-icon [icon]=\"linkIcon\" size=\"small\"></kendo-svg-icon>\n <span>{{ totalAssociations() }} relationship(s)</span>\n </div>\n } @else {\n <mm-widget-not-configured></mm-widget-not-configured>\n }\n</div>\n\n<!-- Entity Detail Dialog -->\n@if (showDetailDialog) {\n <mm-entity-detail-dialog\n [rtId]=\"detailEntityRtId\"\n [ckTypeId]=\"detailEntityCkTypeId\"\n (closed)=\"onDetailDialogClosed()\">\n </mm-entity-detail-dialog>\n}\n", styles: [".associations-widget{display:flex;flex-direction:column;height:100%}.associations-widget.no-data{justify-content:center;align-items:center;color:var(--kendo-color-subtle, #6c757d)}.entity-header{display:flex;align-items:center;gap:12px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.entity-header .entity-box{display:flex;align-items:center;justify-content:center;padding:8px 16px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);border-radius:4px;font-weight:600;font-size:.875rem}.entity-header .entity-details{display:flex;flex-direction:column;gap:2px}.entity-header .entity-id{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);font-family:monospace}.entity-attributes{padding:4px 12px 8px;border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.entity-attributes .attribute-row{display:flex;justify-content:space-between;padding:2px 0;font-size:.8125rem}.entity-attributes .attribute-name{color:var(--kendo-color-subtle, #6c757d)}.entity-attributes .attribute-value{font-weight:500;color:var(--kendo-color-on-surface, #212529)}.associations-container{flex:1;overflow:auto;padding:8px;display:flex;flex-direction:column;gap:4px}.association-group{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;overflow:hidden}.association-group.expanded .group-header{border-bottom:1px solid var(--kendo-color-border, #dee2e6)}.group-header{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa)}.group-header.clickable{cursor:pointer}.group-header.clickable:hover{background:var(--kendo-color-surface, #ffffff)}.direction-indicator{color:var(--kendo-color-subtle, #6c757d);display:flex;align-items:center;width:20px}.group-info{display:flex;align-items:center;gap:8px;flex:1;font-size:.8125rem}.group-info .role-name{color:var(--kendo-color-subtle, #6c757d);font-style:italic}.group-info .target-type{font-weight:500;color:var(--kendo-color-on-surface, #212529)}.group-info .count-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;background:var(--kendo-color-primary, #0d6efd);color:var(--kendo-color-on-primary, #fff);border-radius:10px;font-size:.6875rem;font-weight:600}.expand-icon{color:var(--kendo-color-subtle, #6c757d);display:flex;align-items:center}.target-list{padding:4px 0;max-height:200px;overflow-y:auto}.target-entry+.target-entry{border-top:1px solid var(--kendo-color-border, #dee2e6)}.target-item{display:flex;align-items:center;gap:8px;padding:6px 12px 6px 40px;cursor:pointer;font-size:.8125rem;transition:background .15s ease}.target-item:hover{background:var(--kendo-color-surface-alt, #f8f9fa)}.target-item .target-id{font-family:monospace;color:var(--kendo-color-on-surface, #212529);flex-shrink:0}.target-item .target-type-hint{font-size:.6875rem;color:var(--kendo-color-subtle, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex-shrink:1}.target-attributes{padding:2px 12px 6px 56px}.target-attributes .target-attr-row{display:flex;justify-content:space-between;padding:1px 0;font-size:.75rem}.target-attributes .target-attr-name{color:var(--kendo-color-subtle, #6c757d)}.target-attributes .target-attr-value{color:var(--kendo-color-on-surface, #212529);font-weight:500}.target-loading{padding:6px 12px 6px 40px;font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.associations-summary{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--kendo-color-surface-alt, #f8f9fa);border-top:1px solid var(--kendo-color-border, #dee2e6);font-size:.75rem;color:var(--kendo-color-subtle, #6c757d)}.no-data-message{font-size:.875rem}.loading-indicator{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-subtle, #6c757d)}.error-message{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-error, #dc3545)}\n"] }]
7776
7960
  }], propDecorators: { config: [{
@@ -7825,10 +8009,10 @@ class GetCkTypeAssociationRolesDtoGQL extends i1.Query {
7825
8009
  constructor(apollo) {
7826
8010
  super(apollo);
7827
8011
  }
7828
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7829
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, providedIn: 'root' });
8012
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, deps: [{ token: i1.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
8013
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, providedIn: 'root' });
7830
8014
  }
7831
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, decorators: [{
8015
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, decorators: [{
7832
8016
  type: Injectable,
7833
8017
  args: [{
7834
8018
  providedIn: 'root'
@@ -8257,8 +8441,8 @@ class AssociationsConfigDialogComponent {
8257
8441
  onCancel() {
8258
8442
  this.windowRef.close();
8259
8443
  }
8260
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AssociationsConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8261
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: AssociationsConfigDialogComponent, isStandalone: true, selector: "mm-associations-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialRtId: "initialRtId", initialShowIncoming: "initialShowIncoming", initialShowOutgoing: "initialShowOutgoing", initialRoleFilter: "initialRoleFilter", initialDisplayMode: "initialDisplayMode", initialEntityAttributePaths: "initialEntityAttributePaths", initialTargetAttributePaths: "initialTargetAttributePaths" }, ngImport: i0, template: `
8444
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AssociationsConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8445
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: AssociationsConfigDialogComponent, isStandalone: true, selector: "mm-associations-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialRtId: "initialRtId", initialShowIncoming: "initialShowIncoming", initialShowOutgoing: "initialShowOutgoing", initialRoleFilter: "initialRoleFilter", initialDisplayMode: "initialDisplayMode", initialEntityAttributePaths: "initialEntityAttributePaths", initialTargetAttributePaths: "initialTargetAttributePaths" }, ngImport: i0, template: `
8262
8446
  <div class="config-container">
8263
8447
 
8264
8448
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -8435,7 +8619,7 @@ class AssociationsConfigDialogComponent {
8435
8619
  </div>
8436
8620
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;flex:1;overflow-y:auto;gap:16px;padding:16px;position:relative}.config-form.loading{pointer-events:none}.form-field{display:flex;flex-direction:column;gap:6px}.form-field.disabled{opacity:.6}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.checkbox-group,.radio-group{display:flex;gap:16px}.checkbox-label,.radio-label{display:flex;align-items:center;gap:6px;font-weight:400;cursor:pointer}.loading-roles{padding:8px;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.selection-preview{padding:12px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.selection-preview h4{margin:0 0 8px;font-size:.9rem;color:var(--kendo-color-primary, #0d6efd)}.preview-content p{margin:4px 0;font-size:.85rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "ngmodule", type: CheckBoxModule }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i4.MultiSelectComponent, selector: "kendo-multiselect", inputs: ["showStickyHeader", "focusableId", "autoClose", "loading", "data", "value", "valueField", "textField", "tabindex", "tabIndex", "size", "rounded", "fillMode", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "disabled", "itemDisabled", "checkboxes", "readonly", "filterable", "virtual", "popupSettings", "listHeight", "valuePrimitive", "clearButton", "tagMapper", "allowCustom", "valueNormalizer", "inputAttributes"], outputs: ["filterChange", "valueChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "removeTag"], exportAs: ["kendoMultiSelect"] }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
8437
8621
  }
8438
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AssociationsConfigDialogComponent, decorators: [{
8622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AssociationsConfigDialogComponent, decorators: [{
8439
8623
  type: Component,
8440
8624
  args: [{ selector: 'mm-associations-config-dialog', standalone: true, imports: [
8441
8625
  CommonModule,
@@ -8911,15 +9095,15 @@ class TableWidgetDataSourceDirective extends OctoGraphQlDataSource {
8911
9095
  }
8912
9096
  return { ...timeArgs, rtIds };
8913
9097
  }
8914
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: TableWidgetDataSourceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
8915
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: TableWidgetDataSourceDirective, isStandalone: true, selector: "[mmTableWidgetDataSource]", inputs: { config: "config" }, outputs: { queryColumnsLoaded: "queryColumnsLoaded" }, providers: [
9098
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TableWidgetDataSourceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
9099
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.5", type: TableWidgetDataSourceDirective, isStandalone: true, selector: "[mmTableWidgetDataSource]", inputs: { config: "config" }, outputs: { queryColumnsLoaded: "queryColumnsLoaded" }, providers: [
8916
9100
  {
8917
9101
  provide: DataSourceBase,
8918
9102
  useExisting: forwardRef(() => TableWidgetDataSourceDirective)
8919
9103
  }
8920
9104
  ], exportAs: ["mmTableWidgetDataSource"], usesInheritance: true, ngImport: i0 });
8921
9105
  }
8922
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: TableWidgetDataSourceDirective, decorators: [{
9106
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TableWidgetDataSourceDirective, decorators: [{
8923
9107
  type: Directive,
8924
9108
  args: [{
8925
9109
  selector: '[mmTableWidgetDataSource]',
@@ -9079,8 +9263,8 @@ class TableWidgetComponent {
9079
9263
  this.dataSource.fetchAgain();
9080
9264
  }
9081
9265
  }
9082
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: TableWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9083
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: TableWidgetComponent, isStandalone: true, selector: "mm-table-widget", inputs: { config: "config" }, viewQueries: [{ propertyName: "dataSource", first: true, predicate: ["dataSource"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
9266
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TableWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9267
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: TableWidgetComponent, isStandalone: true, selector: "mm-table-widget", inputs: { config: "config" }, viewQueries: [{ propertyName: "dataSource", first: true, predicate: ["dataSource"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
9084
9268
  <div class="table-widget">
9085
9269
  @if (hasValidConfig()) {
9086
9270
  <mm-list-view
@@ -9106,7 +9290,7 @@ class TableWidgetComponent {
9106
9290
  </div>
9107
9291
  `, isInline: true, styles: [".table-widget{height:100%;width:100%;display:flex;flex-direction:column}.no-config-overlay{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-subtle, #6c757d);font-style:italic}:host ::ng-deep mm-list-view{height:100%}:host ::ng-deep .k-grid{height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ListViewComponent, selector: "mm-list-view", inputs: ["pageSize", "skip", "rowIsClickable", "showRowCheckBoxes", "showRowSelectAllCheckBox", "contextMenuType", "leftToolbarActions", "rightToolbarActions", "actionCommandItems", "contextMenuCommandItems", "excelExportFileName", "pdfExportFileName", "pageable", "sortable", "rowFilterEnabled", "searchTextBoxEnabled", "rowClass", "messages", "selectable", "columns"], outputs: ["rowClicked"] }, { kind: "directive", type: TableWidgetDataSourceDirective, selector: "[mmTableWidgetDataSource]", inputs: ["config"], outputs: ["queryColumnsLoaded"], exportAs: ["mmTableWidgetDataSource"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
9108
9292
  }
9109
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: TableWidgetComponent, decorators: [{
9293
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TableWidgetComponent, decorators: [{
9110
9294
  type: Component,
9111
9295
  args: [{ selector: 'mm-table-widget', standalone: true, imports: [
9112
9296
  CommonModule,
@@ -9433,8 +9617,8 @@ class TableConfigDialogComponent {
9433
9617
  onCancel() {
9434
9618
  this.windowRef.close();
9435
9619
  }
9436
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: TableConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9437
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: TableConfigDialogComponent, isStandalone: true, selector: "mm-table-config-dialog", inputs: { initialDataSourceType: "initialDataSourceType", initialCkTypeId: "initialCkTypeId", initialColumns: "initialColumns", initialSorting: "initialSorting", initialFilters: "initialFilters", initialPageSize: "initialPageSize", initialSortable: "initialSortable", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId" }, providers: [
9620
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TableConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9621
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: TableConfigDialogComponent, isStandalone: true, selector: "mm-table-config-dialog", inputs: { initialDataSourceType: "initialDataSourceType", initialCkTypeId: "initialCkTypeId", initialColumns: "initialColumns", initialSorting: "initialSorting", initialFilters: "initialFilters", initialPageSize: "initialPageSize", initialSortable: "initialSortable", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId" }, providers: [
9438
9622
  AttributeSelectorDialogService,
9439
9623
  AttributeSortSelectorDialogService
9440
9624
  ], viewQueries: [{ propertyName: "ckTypeSelectorInput", first: true, predicate: ["ckTypeSelector"], descendants: true }, { propertyName: "filterEditor", first: true, predicate: ["filterEditor"], descendants: true }, { propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
@@ -9650,7 +9834,7 @@ class TableConfigDialogComponent {
9650
9834
  </div>
9651
9835
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:16px;flex:1;overflow-y:auto;padding:16px;position:relative}.config-form.loading{pointer-events:none}.form-field{display:flex;flex-direction:column;gap:6px}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.required{color:var(--kendo-color-error, #dc3545)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.config-card{padding:12px 16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.card-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.card-header kendo-svgicon{color:var(--kendo-color-primary, #0d6efd)}.card-title{font-weight:600;font-size:.95rem;color:var(--kendo-color-primary, #0d6efd)}.card-count{color:var(--kendo-color-subtle, #6c757d);font-size:.85rem}.card-content{display:flex;align-items:center;justify-content:space-between;gap:16px}.config-summary{margin:0;font-size:.85rem;color:var(--kendo-color-on-app-surface, #212529);flex:1}.filters-card .card-content{flex-direction:column;align-items:stretch}.filter-content{width:100%}.options-card .options-content{display:flex;gap:24px;align-items:flex-end}.checkbox-field{flex-direction:row;align-items:center}.checkbox-field label{display:flex;align-items:center;gap:8px;cursor:pointer;color:var(--kendo-color-on-app-surface, #212529)}.data-source-type .radio-group{display:flex;gap:24px}.radio-label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400;color:var(--kendo-color-on-app-surface, #212529)}.radio-label span{color:var(--kendo-color-on-app-surface, #212529)}.query-info{flex-direction:column;align-items:stretch;gap:8px}.info-row{display:flex;gap:8px}.info-label{font-weight:600;min-width:100px;color:var(--kendo-color-subtle, #6c757d)}.info-value{flex:1;color:var(--kendo-color-on-app-surface, #212529)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "directive", type: i3.RadioButtonDirective, selector: "input[kendoRadioButton]", inputs: ["size"] }, { kind: "ngmodule", type: NumericTextBoxModule }, { kind: "ngmodule", type: DropDownsModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: QuerySelectorComponent, selector: "mm-query-selector", inputs: ["placeholder", "hint", "disabled", "acceptFamilies"], outputs: ["querySelected", "queriesLoaded"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
9652
9836
  }
9653
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: TableConfigDialogComponent, decorators: [{
9837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TableConfigDialogComponent, decorators: [{
9654
9838
  type: Component,
9655
9839
  args: [{ selector: 'mm-table-config-dialog', standalone: true, imports: [
9656
9840
  CommonModule,
@@ -10155,8 +10339,8 @@ class GaugeWidgetComponent {
10155
10339
  const variables = this.stateService.getVariables();
10156
10340
  return this.variableService.convertToFieldFilterDto(filters, variables);
10157
10341
  }
10158
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GaugeWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10159
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: GaugeWidgetComponent, isStandalone: true, selector: "mm-gauge-widget", inputs: { config: "config" }, providers: [CollectionChangesService], usesOnChanges: true, ngImport: i0, template: `
10342
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GaugeWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10343
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: GaugeWidgetComponent, isStandalone: true, selector: "mm-gauge-widget", inputs: { config: "config" }, providers: [CollectionChangesService], usesOnChanges: true, ngImport: i0, template: `
10160
10344
  <div class="gauge-widget" [class.loading]="isLoading()" [class.error]="error()">
10161
10345
  @if (isNotConfigured()) {
10162
10346
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -10327,7 +10511,7 @@ class GaugeWidgetComponent {
10327
10511
  </div>
10328
10512
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.gauge-widget{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:8px;box-sizing:border-box;overflow:hidden}.gauge-widget.loading,.gauge-widget.error{opacity:.7}.loading-indicator,.error-message{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.loading-indicator span{font-size:1.5rem;color:var(--kendo-color-subtle, #6c757d)}.error-message span{color:var(--kendo-color-error, #dc3545);font-size:.875rem}.gauge-container{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%}.gauge-center-label{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}.gauge-center-label .value-text{font-size:1.25rem;font-weight:600;color:var(--kendo-color-on-surface, inherit)}.gauge-center-label .label-text{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);margin-top:2px}.gauge-value-label{display:flex;flex-direction:column;align-items:center;margin-top:8px;font-size:1.1rem;font-weight:600;color:var(--kendo-color-on-surface, inherit)}.gauge-value-label .label-text{font-size:.75rem;font-weight:400;color:var(--kendo-color-subtle, #6c757d);margin-top:2px}kendo-arcgauge,kendo-circulargauge,kendo-radialgauge{width:100%;max-width:200px;height:auto}.linear-gauge-wrapper{display:flex;flex-direction:row;align-items:center;justify-content:center;height:100%;width:100%;gap:8px}.linear-gauge-wrapper .gauge-value-label{margin-top:0;writing-mode:horizontal-tb}kendo-lineargauge{height:100%;max-height:180px;width:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i1$6.ArcGaugeComponent, selector: "kendo-arcgauge", inputs: ["value", "color", "colors", "opacity", "scale"], exportAs: ["kendoArcGauge"] }, { kind: "directive", type: i1$6.ArcCenterTemplateDirective, selector: "[kendoArcGaugeCenterTemplate]" }, { kind: "component", type: i1$6.ArcScaleComponent, selector: "kendo-arcgauge-scale", inputs: ["labels", "rangeDistance", "rangeLineCap", "startAngle", "endAngle"] }, { kind: "component", type: i1$6.ColorsComponent, selector: "kendo-arcgauge-colors" }, { kind: "component", type: i1$6.ColorComponent, selector: "kendo-arcgauge-color", inputs: ["color", "opacity", "from", "to"] }, { kind: "component", type: i1$6.CircularGaugeComponent, selector: "kendo-circulargauge", inputs: ["scale"], exportAs: ["kendoCircularGauge"] }, { kind: "directive", type: i1$6.CircularGaugeCenterTemplateDirective, selector: "[kendoCircularGaugeCenterTemplate]" }, { kind: "component", type: i1$6.CircularGaugeScaleComponent, selector: "kendo-circulargauge-scale" }, { kind: "component", type: i1$6.LinearGaugeComponent, selector: "kendo-lineargauge", inputs: ["pointer", "scale"], exportAs: ["kendoLinearGauge"] }, { kind: "component", type: i1$6.LinearScaleComponent, selector: "kendo-lineargauge-scale", inputs: ["line", "ranges", "mirror", "vertical"] }, { kind: "component", type: i1$6.LinearLabelsComponent, selector: "kendo-lineargauge-scale-labels" }, { kind: "component", type: i1$6.LinearPointersComponent, selector: "kendo-lineargauge-pointers" }, { kind: "component", type: i1$6.LinearPointerComponent, selector: "kendo-lineargauge-pointer", inputs: ["border", "color", "margin", "opacity", "shape", "size", "value"] }, { kind: "component", type: i1$6.LinearRangeComponent, selector: "kendo-lineargauge-scale-range" }, { kind: "component", type: i1$6.LinearRangesComponent, selector: "kendo-lineargauge-scale-ranges" }, { kind: "component", type: i1$6.RadialGaugeComponent, selector: "kendo-radialgauge", inputs: ["pointer", "scale"], exportAs: ["kendoRadialGauge"] }, { kind: "component", type: i1$6.RadialScaleComponent, selector: "kendo-radialgauge-scale", inputs: ["labels", "rangeDistance", "ranges", "startAngle", "endAngle"] }, { kind: "component", type: i1$6.RadialPointerComponent, selector: "kendo-radialgauge-pointer", inputs: ["cap", "color", "length", "value"] }, { kind: "component", type: i1$6.RadialRangeComponent, selector: "kendo-radialgauge-scale-range" }, { kind: "component", type: i1$6.RadialRangesComponent, selector: "kendo-radialgauge-scale-ranges" }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
10329
10513
  }
10330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GaugeWidgetComponent, decorators: [{
10514
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GaugeWidgetComponent, decorators: [{
10331
10515
  type: Component,
10332
10516
  args: [{ selector: 'mm-gauge-widget', standalone: true, imports: [
10333
10517
  CommonModule,
@@ -10989,8 +11173,8 @@ class GaugeConfigDialogComponent {
10989
11173
  onFiltersChange(updatedFilters) {
10990
11174
  this.filters = updatedFilters;
10991
11175
  }
10992
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GaugeConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10993
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: GaugeConfigDialogComponent, isStandalone: true, selector: "mm-gauge-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialRtId: "initialRtId", initialGaugeType: "initialGaugeType", initialValueAttribute: "initialValueAttribute", initialLabelAttribute: "initialLabelAttribute", initialMin: "initialMin", initialMax: "initialMax", initialRanges: "initialRanges", initialShowLabel: "initialShowLabel", initialPrefix: "initialPrefix", initialSuffix: "initialSuffix", initialReverse: "initialReverse", initialDataSourceType: "initialDataSourceType", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialQueryMode: "initialQueryMode", initialQueryValueField: "initialQueryValueField", initialQueryCategoryField: "initialQueryCategoryField", initialQueryCategoryValue: "initialQueryCategoryValue", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "ckTypeSelectorInput", first: true, predicate: ["ckTypeSelector"], descendants: true }, { propertyName: "entitySelectorInput", first: true, predicate: ["entitySelector"], descendants: true }, { propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
11176
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GaugeConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11177
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: GaugeConfigDialogComponent, isStandalone: true, selector: "mm-gauge-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialRtId: "initialRtId", initialGaugeType: "initialGaugeType", initialValueAttribute: "initialValueAttribute", initialLabelAttribute: "initialLabelAttribute", initialMin: "initialMin", initialMax: "initialMax", initialRanges: "initialRanges", initialShowLabel: "initialShowLabel", initialPrefix: "initialPrefix", initialSuffix: "initialSuffix", initialReverse: "initialReverse", initialDataSourceType: "initialDataSourceType", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialQueryMode: "initialQueryMode", initialQueryValueField: "initialQueryValueField", initialQueryCategoryField: "initialQueryCategoryField", initialQueryCategoryValue: "initialQueryCategoryValue", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "ckTypeSelectorInput", first: true, predicate: ["ckTypeSelector"], descendants: true }, { propertyName: "entitySelectorInput", first: true, predicate: ["entitySelector"], descendants: true }, { propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
10994
11178
  <div class="config-container">
10995
11179
 
10996
11180
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -11402,7 +11586,7 @@ class GaugeConfigDialogComponent {
11402
11586
  </div>
11403
11587
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:20px;padding:16px;position:relative;flex:1;overflow-y:auto}.config-form.loading{pointer-events:none}.form-field{display:flex;flex-direction:column;gap:6px}.form-field.disabled{opacity:.6}.form-field.flex-1{flex:1}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.form-section h4{margin:0 0 16px;font-size:.95rem;color:var(--kendo-color-primary, #0d6efd)}.section-hint{margin:0 0 12px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.form-row{display:flex;gap:16px}.checkbox-label{margin-left:8px;font-weight:400}.gauge-type-item{display:flex;flex-direction:column;gap:2px}.gauge-type-label{font-weight:500}.gauge-type-desc{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d)}.attribute-item{display:flex;justify-content:space-between;align-items:center;gap:8px;width:100%}.attribute-path{flex:1}.attribute-type{font-size:.75rem;color:var(--kendo-color-subtle, #6c757d);background:var(--kendo-color-surface-alt, #f8f9fa);padding:2px 6px;border-radius:3px}.range-row{display:flex;align-items:center;gap:8px;margin-bottom:8px}.range-input{width:80px}.range-separator{color:var(--kendo-color-subtle, #6c757d)}.color-picker{width:40px;height:32px;padding:2px;border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;cursor:pointer}.mode-toggle{display:flex;gap:8px}.mode-toggle button{flex:1}.required{color:var(--kendo-color-error, #dc3545)}.query-item{display:flex;flex-direction:column;gap:2px}.query-name{font-weight:500}.query-description{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.column-item{display:flex;justify-content:space-between;gap:16px}.column-path{font-weight:500}.column-type{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: QuerySelectorComponent, selector: "mm-query-selector", inputs: ["placeholder", "hint", "disabled", "acceptFamilies"], outputs: ["querySelected", "queriesLoaded"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
11404
11588
  }
11405
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: GaugeConfigDialogComponent, decorators: [{
11589
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: GaugeConfigDialogComponent, decorators: [{
11406
11590
  type: Component,
11407
11591
  args: [{ selector: 'mm-gauge-config-dialog', standalone: true, imports: [
11408
11592
  CommonModule,
@@ -12082,8 +12266,8 @@ class PieChartWidgetComponent {
12082
12266
  const variables = this.stateService.getVariables();
12083
12267
  return this.variableService.convertToFieldFilterDto(filters, variables);
12084
12268
  }
12085
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PieChartWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12086
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: PieChartWidgetComponent, isStandalone: true, selector: "mm-pie-chart-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
12269
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: PieChartWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12270
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: PieChartWidgetComponent, isStandalone: true, selector: "mm-pie-chart-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
12087
12271
  <div class="pie-chart-widget" [class.loading]="isLoading()" [class.error]="error()">
12088
12272
  @if (isNotConfigured()) {
12089
12273
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -12123,7 +12307,7 @@ class PieChartWidgetComponent {
12123
12307
  </div>
12124
12308
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.pie-chart-widget{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:8px;box-sizing:border-box;overflow:hidden}.pie-chart-widget.loading,.pie-chart-widget.error{opacity:.7}.loading-indicator,.error-message,.no-config-overlay{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.loading-indicator span{font-size:1.5rem;color:var(--kendo-color-subtle, #6c757d)}.error-message span{color:var(--kendo-color-error, #dc3545);font-size:.875rem}.no-config-overlay span{color:var(--kendo-color-subtle, #6c757d);font-style:italic}.chart-container{width:100%;height:100%}kendo-chart{width:100%;height:100%}.chart-tooltip{padding:4px 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ChartsModule }, { kind: "component", type: i1$7.ChartComponent, selector: "kendo-chart", inputs: ["pannable", "renderAs", "seriesColors", "subtitle", "title", "noData", "observeStyles", "transitions", "zoomable", "axisDefaults", "categoryAxis", "chartArea", "legend", "panes", "paneDefaults", "plotArea", "series", "seriesDefaults", "tooltip", "valueAxis", "xAxis", "yAxis", "resizeRateLimit", "popupSettings", "drilldownLevel"], outputs: ["axisLabelClick", "drag", "dragEnd", "dragStart", "legendItemHover", "legendItemLeave", "noteClick", "noteHover", "noteLeave", "paneRender", "plotAreaClick", "plotAreaHover", "plotAreaLeave", "render", "select", "selectEnd", "selectStart", "seriesClick", "drilldown", "seriesHover", "seriesOver", "seriesLeave", "zoom", "zoomEnd", "zoomStart", "legendItemClick", "drilldownLevelChange"], exportAs: ["kendoChart"] }, { kind: "directive", type: i1$7.SeriesTooltipTemplateDirective, selector: "[kendoChartSeriesTooltipTemplate]" }, { kind: "component", type: i1$7.ChartAreaComponent, selector: "kendo-chart-area", inputs: ["background", "border", "height", "margin", "opacity", "width"] }, { kind: "component", type: i1$7.LegendComponent, selector: "kendo-chart-legend", inputs: ["align", "background", "border", "height", "labels", "margin", "offsetX", "offsetY", "orientation", "padding", "position", "reverse", "visible", "width", "markers", "spacing", "inactiveItems", "item", "title", "focusHighlight"] }, { kind: "component", type: i1$7.SeriesComponent, selector: "kendo-chart-series" }, { kind: "component", type: i1$7.SeriesItemComponent, selector: "kendo-chart-series-item", inputs: ["aggregate", "autoFit", "axis", "border", "categoryAxis", "categoryField", "closeField", "color", "colorField", "connectors", "currentField", "dashType", "data", "downColor", "downColorField", "drilldownField", "dynamicHeight", "dynamicSlope", "errorHighField", "errorLowField", "explodeField", "field", "fromField", "gap", "highField", "holeSize", "line", "lowField", "lowerField", "margin", "maxSize", "mean", "meanField", "median", "medianField", "minSize", "missingValues", "name", "neckRatio", "negativeColor", "negativeValues", "noteTextField", "opacity", "openField", "outliersField", "overlay", "padding", "q1Field", "q3Field", "segmentSpacing", "size", "sizeField", "spacing", "stack", "startAngle", "lineStyle", "summaryField", "target", "toField", "type", "upperField", "visible", "visibleInLegend", "visibleInLegendField", "visual", "width", "whiskers", "xAxis", "xErrorHighField", "xErrorLowField", "xField", "yAxis", "yErrorHighField", "yErrorLowField", "yField", "zIndex", "trendline", "for", "legendItem", "pattern", "patternField", "errorBars", "extremes", "highlight", "labels", "markers", "notes", "outliers", "tooltip"] }, { kind: "component", type: i1$7.TooltipComponent, selector: "kendo-chart-tooltip", inputs: ["background", "border", "color", "font", "format", "opacity", "padding", "shared", "visible"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
12125
12309
  }
12126
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PieChartWidgetComponent, decorators: [{
12310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: PieChartWidgetComponent, decorators: [{
12127
12311
  type: Component,
12128
12312
  args: [{ selector: 'mm-pie-chart-widget', standalone: true, imports: [
12129
12313
  CommonModule,
@@ -12456,8 +12640,8 @@ class PieChartConfigDialogComponent {
12456
12640
  onCancel() {
12457
12641
  this.windowRef.close();
12458
12642
  }
12459
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PieChartConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12460
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: PieChartConfigDialogComponent, isStandalone: true, selector: "mm-pie-chart-config-dialog", inputs: { initialDataSourceType: "initialDataSourceType", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialChartType: "initialChartType", initialCategoryField: "initialCategoryField", initialValueField: "initialValueField", initialShowLabels: "initialShowLabels", initialShowLegend: "initialShowLegend", initialLegendPosition: "initialLegendPosition", initialCkQueryTarget: "initialCkQueryTarget", initialCkGroupBy: "initialCkGroupBy", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
12643
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: PieChartConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12644
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: PieChartConfigDialogComponent, isStandalone: true, selector: "mm-pie-chart-config-dialog", inputs: { initialDataSourceType: "initialDataSourceType", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialChartType: "initialChartType", initialCategoryField: "initialCategoryField", initialValueField: "initialValueField", initialShowLabels: "initialShowLabels", initialShowLegend: "initialShowLegend", initialLegendPosition: "initialLegendPosition", initialCkQueryTarget: "initialCkQueryTarget", initialCkGroupBy: "initialCkGroupBy", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
12461
12645
  <div class="config-container">
12462
12646
 
12463
12647
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -12669,7 +12853,7 @@ class PieChartConfigDialogComponent {
12669
12853
  </div>
12670
12854
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;flex:1;overflow-y:auto;gap:20px;padding:16px;position:relative}.config-form.loading{pointer-events:none}.config-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.section-title{margin:0 0 16px;font-size:1rem;font-weight:600;color:var(--kendo-color-primary, #0d6efd)}.section-hint{margin:0 0 12px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}.form-field:last-child{margin-bottom:0}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.required{color:var(--kendo-color-error, #dc3545)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.radio-group{display:flex;gap:24px}.radio-label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400}.query-item{display:flex;flex-direction:column;gap:2px}.query-name{font-weight:500}.query-description{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.column-item{display:flex;justify-content:space-between;gap:16px}.column-path{font-weight:500}.column-type{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "directive", type: i3.RadioButtonDirective, selector: "input[kendoRadioButton]", inputs: ["size"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: QuerySelectorComponent, selector: "mm-query-selector", inputs: ["placeholder", "hint", "disabled", "acceptFamilies"], outputs: ["querySelected", "queriesLoaded"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
12671
12855
  }
12672
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PieChartConfigDialogComponent, decorators: [{
12856
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: PieChartConfigDialogComponent, decorators: [{
12673
12857
  type: Component,
12674
12858
  args: [{ selector: 'mm-pie-chart-config-dialog', standalone: true, imports: [
12675
12859
  CommonModule,
@@ -13255,8 +13439,8 @@ class BarChartWidgetComponent {
13255
13439
  const variables = this.stateService.getVariables();
13256
13440
  return this.variableService.convertToFieldFilterDto(filters, variables);
13257
13441
  }
13258
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BarChartWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13259
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BarChartWidgetComponent, isStandalone: true, selector: "mm-bar-chart-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
13442
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BarChartWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13443
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: BarChartWidgetComponent, isStandalone: true, selector: "mm-bar-chart-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
13260
13444
  <div class="bar-chart-widget" [class.loading]="isLoading()" [class.error]="error()">
13261
13445
  @if (isNotConfigured()) {
13262
13446
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -13330,7 +13514,7 @@ class BarChartWidgetComponent {
13330
13514
  </div>
13331
13515
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.bar-chart-widget{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:8px;box-sizing:border-box;overflow:hidden}.bar-chart-widget.loading,.bar-chart-widget.error{opacity:.7}.loading-indicator,.error-message,.no-config-overlay{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.loading-indicator span{font-size:1.5rem;color:var(--kendo-color-subtle, #6c757d)}.error-message span{color:var(--kendo-color-error, #dc3545);font-size:.875rem}.no-config-overlay span{color:var(--kendo-color-subtle, #6c757d);font-style:italic}.chart-container{width:100%;height:100%}kendo-chart{width:100%;height:100%}.chart-tooltip{padding:4px 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ChartsModule }, { kind: "component", type: i1$7.ChartComponent, selector: "kendo-chart", inputs: ["pannable", "renderAs", "seriesColors", "subtitle", "title", "noData", "observeStyles", "transitions", "zoomable", "axisDefaults", "categoryAxis", "chartArea", "legend", "panes", "paneDefaults", "plotArea", "series", "seriesDefaults", "tooltip", "valueAxis", "xAxis", "yAxis", "resizeRateLimit", "popupSettings", "drilldownLevel"], outputs: ["axisLabelClick", "drag", "dragEnd", "dragStart", "legendItemHover", "legendItemLeave", "noteClick", "noteHover", "noteLeave", "paneRender", "plotAreaClick", "plotAreaHover", "plotAreaLeave", "render", "select", "selectEnd", "selectStart", "seriesClick", "drilldown", "seriesHover", "seriesOver", "seriesLeave", "zoom", "zoomEnd", "zoomStart", "legendItemClick", "drilldownLevelChange"], exportAs: ["kendoChart"] }, { kind: "directive", type: i1$7.SeriesTooltipTemplateDirective, selector: "[kendoChartSeriesTooltipTemplate]" }, { kind: "component", type: i1$7.CategoryAxisComponent, selector: "kendo-chart-category-axis" }, { kind: "component", type: i1$7.CategoryAxisItemComponent, selector: "kendo-chart-category-axis-item", inputs: ["autoBaseUnitSteps", "axisCrossingValue", "background", "baseUnit", "baseUnitStep", "categories", "color", "justified", "line", "majorGridLines", "majorTicks", "max", "maxDateGroups", "maxDivisions", "min", "minorGridLines", "minorTicks", "name", "pane", "plotBands", "reverse", "roundToBaseUnit", "startAngle", "type", "visible", "weekStartDay", "crosshair", "labels", "notes", "select", "title", "rangeLabels", "highlight"] }, { kind: "component", type: i1$7.CategoryAxisLabelsComponent, selector: "kendo-chart-category-axis-item-labels", inputs: ["background", "border", "color", "content", "culture", "dateFormats", "font", "format", "margin", "mirror", "padding", "position", "rotation", "skip", "step", "visible", "visual"] }, { kind: "component", type: i1$7.ChartAreaComponent, selector: "kendo-chart-area", inputs: ["background", "border", "height", "margin", "opacity", "width"] }, { kind: "component", type: i1$7.LegendComponent, selector: "kendo-chart-legend", inputs: ["align", "background", "border", "height", "labels", "margin", "offsetX", "offsetY", "orientation", "padding", "position", "reverse", "visible", "width", "markers", "spacing", "inactiveItems", "item", "title", "focusHighlight"] }, { kind: "component", type: i1$7.SeriesComponent, selector: "kendo-chart-series" }, { kind: "component", type: i1$7.SeriesItemComponent, selector: "kendo-chart-series-item", inputs: ["aggregate", "autoFit", "axis", "border", "categoryAxis", "categoryField", "closeField", "color", "colorField", "connectors", "currentField", "dashType", "data", "downColor", "downColorField", "drilldownField", "dynamicHeight", "dynamicSlope", "errorHighField", "errorLowField", "explodeField", "field", "fromField", "gap", "highField", "holeSize", "line", "lowField", "lowerField", "margin", "maxSize", "mean", "meanField", "median", "medianField", "minSize", "missingValues", "name", "neckRatio", "negativeColor", "negativeValues", "noteTextField", "opacity", "openField", "outliersField", "overlay", "padding", "q1Field", "q3Field", "segmentSpacing", "size", "sizeField", "spacing", "stack", "startAngle", "lineStyle", "summaryField", "target", "toField", "type", "upperField", "visible", "visibleInLegend", "visibleInLegendField", "visual", "width", "whiskers", "xAxis", "xErrorHighField", "xErrorLowField", "xField", "yAxis", "yErrorHighField", "yErrorLowField", "yField", "zIndex", "trendline", "for", "legendItem", "pattern", "patternField", "errorBars", "extremes", "highlight", "labels", "markers", "notes", "outliers", "tooltip"] }, { kind: "component", type: i1$7.SeriesLabelsComponent, selector: "kendo-chart-series-item-labels", inputs: ["align", "background", "border", "color", "content", "ariaContent", "distance", "font", "format", "margin", "padding", "position", "rotation", "visible", "visual", "from", "to"] }, { kind: "component", type: i1$7.TooltipComponent, selector: "kendo-chart-tooltip", inputs: ["background", "border", "color", "font", "format", "opacity", "padding", "shared", "visible"] }, { kind: "component", type: i1$7.ValueAxisComponent, selector: "kendo-chart-value-axis" }, { kind: "component", type: i1$7.ValueAxisItemComponent, selector: "kendo-chart-value-axis-item", inputs: ["axisCrossingValue", "background", "color", "line", "majorGridLines", "majorTicks", "majorUnit", "max", "min", "minorGridLines", "minorTicks", "minorUnit", "name", "narrowRange", "pane", "plotBands", "reverse", "type", "visible", "crosshair", "labels", "notes", "title"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
13332
13516
  }
13333
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BarChartWidgetComponent, decorators: [{
13517
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BarChartWidgetComponent, decorators: [{
13334
13518
  type: Component,
13335
13519
  args: [{ selector: 'mm-bar-chart-widget', standalone: true, imports: [
13336
13520
  CommonModule,
@@ -13697,8 +13881,8 @@ class BarChartConfigDialogComponent {
13697
13881
  onCancel() {
13698
13882
  this.windowRef.close();
13699
13883
  }
13700
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BarChartConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13701
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BarChartConfigDialogComponent, isStandalone: true, selector: "mm-bar-chart-config-dialog", inputs: { initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialChartType: "initialChartType", initialCategoryField: "initialCategoryField", initialSeries: "initialSeries", initialSeriesGroupField: "initialSeriesGroupField", initialValueField: "initialValueField", initialShowLegend: "initialShowLegend", initialLegendPosition: "initialLegendPosition", initialShowDataLabels: "initialShowDataLabels", initialColorThresholds: "initialColorThresholds", initialDefaultBarColor: "initialDefaultBarColor", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
13884
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BarChartConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13885
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: BarChartConfigDialogComponent, isStandalone: true, selector: "mm-bar-chart-config-dialog", inputs: { initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialChartType: "initialChartType", initialCategoryField: "initialCategoryField", initialSeries: "initialSeries", initialSeriesGroupField: "initialSeriesGroupField", initialValueField: "initialValueField", initialShowLegend: "initialShowLegend", initialLegendPosition: "initialLegendPosition", initialShowDataLabels: "initialShowDataLabels", initialColorThresholds: "initialColorThresholds", initialDefaultBarColor: "initialDefaultBarColor", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
13702
13886
  <div class="config-container">
13703
13887
 
13704
13888
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -13972,7 +14156,7 @@ class BarChartConfigDialogComponent {
13972
14156
  </div>
13973
14157
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:20px;flex:1;overflow-y:auto;padding:16px;position:relative}.config-form.loading{pointer-events:none}.config-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.section-title{margin:0 0 16px;font-size:1rem;font-weight:600;color:var(--kendo-color-primary, #0d6efd)}.section-hint{margin:0 0 12px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}.form-field:last-child{margin-bottom:0}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.required{color:var(--kendo-color-error, #dc3545)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.chart-type-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}.radio-label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400}.form-row{display:flex;gap:24px}.checkbox-field{flex-direction:row;align-items:center}.checkbox-field label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400}.query-item{display:flex;flex-direction:column;gap:2px}.query-name{font-weight:500}.query-description{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.column-item{display:flex;justify-content:space-between;gap:16px}.column-path{font-weight:500}.column-type{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-section{margin-top:8px}.form-section h4{margin:0 0 4px;font-size:.95rem;font-weight:600}.threshold-row{display:flex;gap:8px;align-items:center;margin-bottom:8px}.threshold-row label{font-size:.85rem;min-width:70px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "directive", type: i3.RadioButtonDirective, selector: "input[kendoRadioButton]", inputs: ["size"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: i4.MultiSelectComponent, selector: "kendo-multiselect", inputs: ["showStickyHeader", "focusableId", "autoClose", "loading", "data", "value", "valueField", "textField", "tabindex", "tabIndex", "size", "rounded", "fillMode", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "disabled", "itemDisabled", "checkboxes", "readonly", "filterable", "virtual", "popupSettings", "listHeight", "valuePrimitive", "clearButton", "tagMapper", "allowCustom", "valueNormalizer", "inputAttributes"], outputs: ["filterChange", "valueChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "removeTag"], exportAs: ["kendoMultiSelect"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: QuerySelectorComponent, selector: "mm-query-selector", inputs: ["placeholder", "hint", "disabled", "acceptFamilies"], outputs: ["querySelected", "queriesLoaded"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
13974
14158
  }
13975
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BarChartConfigDialogComponent, decorators: [{
14159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BarChartConfigDialogComponent, decorators: [{
13976
14160
  type: Component,
13977
14161
  args: [{ selector: 'mm-bar-chart-config-dialog', standalone: true, imports: [
13978
14162
  CommonModule,
@@ -14298,6 +14482,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
14298
14482
 
14299
14483
  /** Series colours so a series' min/max band and its avg line share one hue. */
14300
14484
  const SERIES_PALETTE = ['#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6', '#ec4899', '#14b8a6', '#f97316'];
14485
+ /**
14486
+ * Resolution-aware routing (AB#4290): only surface the "resolution limited" warning when the line
14487
+ * would be *visibly* steppy — i.e. each delivered point spans at least this many pixels of chart
14488
+ * width. Falling short of the pixel-ideal target is not itself a problem: 240 points on a 1300px
14489
+ * chart (~5.4 px/point) reads perfectly smooth. Only a genuinely coarse rung (few points spread
14490
+ * over a wide chart) is worth flagging. Comparing against a raw point-count ratio cries wolf.
14491
+ */
14492
+ const RESOLUTION_LIMIT_WARN_PX = 12;
14301
14493
  class LineChartWidgetComponent {
14302
14494
  queryExecutor = inject(QueryExecutorService);
14303
14495
  elementRef = inject(ElementRef);
@@ -14334,12 +14526,107 @@ class LineChartWidgetComponent {
14334
14526
  // (e.g. all rows sharing one category/timestamp).
14335
14527
  _dataInfo = signal(null, /* @ts-ignore */
14336
14528
  ...(ngDevMode ? [{ debugName: "_dataInfo" }] : /* istanbul ignore next */ []));
14529
+ // Resolution-aware routing outcome (AB#4290): drives the archive/rollup hint badge so the
14530
+ // user sees when the server delivered fewer points than requested or refused to reduce.
14531
+ _resolutionSignal = signal(null, /* @ts-ignore */
14532
+ ...(ngDevMode ? [{ debugName: "_resolutionSignal" }] : /* istanbul ignore next */ []));
14533
+ // The point count the widget requested (pixel-driven), kept so the resolution-limited hint can
14534
+ // show delivered-vs-requested — the resolver only returns the delivered count in `points`.
14535
+ _resolutionTarget = signal(null, /* @ts-ignore */
14536
+ ...(ngDevMode ? [{ debugName: "_resolutionTarget" }] : /* istanbul ignore next */ []));
14537
+ // Whether the click-through explanation panel for the resolution warning is open.
14538
+ _showResolutionInfo = signal(false, /* @ts-ignore */
14539
+ ...(ngDevMode ? [{ debugName: "_showResolutionInfo" }] : /* istanbul ignore next */ []));
14540
+ showResolutionInfo = this._showResolutionInfo.asReadonly();
14337
14541
  isLoading = this._isLoading.asReadonly();
14338
14542
  categories = this._categories.asReadonly();
14339
14543
  seriesData = this._seriesData.asReadonly();
14340
14544
  valueAxes = this._valueAxes.asReadonly();
14341
14545
  error = this._error.asReadonly();
14342
14546
  dataInfo = this._dataInfo.asReadonly();
14547
+ /**
14548
+ * Resolution-aware hint (AB#4290): a short badge describing the archive-selection outcome —
14549
+ * `null` for a clean reduction (signal OK), a warning otherwise (fewer points delivered, or no
14550
+ * compatible rollup so the raw archive was returned unreduced). Mirrors the resolver's signal.
14551
+ */
14552
+ resolutionHint = computed(() => {
14553
+ const s = this._resolutionSignal();
14554
+ if (!s)
14555
+ return null;
14556
+ const diag = s.diagnostic ?? '';
14557
+ switch (s.signal) {
14558
+ case SeriesResolutionSignalDto.ResolutionLimitedDto: {
14559
+ const delivered = s.actualPoints ?? s.points;
14560
+ const requested = this._resolutionTarget();
14561
+ // Only flag when the line would be *visibly* steppy — each point spans ≥ N px of chart
14562
+ // width. A dense-enough line (e.g. 240 pts on a 1300px chart ≈ 5 px/pt) reads fine even
14563
+ // below the pixel-ideal target, so it must not warn.
14564
+ const width = this.elementRef.nativeElement?.offsetWidth ?? 0;
14565
+ if (width > 0 && delivered > 0 && width / delivered < RESOLUTION_LIMIT_WARN_PX)
14566
+ return null;
14567
+ const ofReq = requested && requested > delivered ? ` (of ${requested})` : '';
14568
+ return { text: `⚠ limited${ofReq}`, title: diag || 'Resolution limited: the coarsest available rollup delivers fewer points than requested for this range.' };
14569
+ }
14570
+ case SeriesResolutionSignalDto.NoSuitableRollupDto:
14571
+ return { text: '⚠ no rollup', title: diag || 'No compatible rollup for this aggregation — the raw archive was returned unreduced.' };
14572
+ case SeriesResolutionSignalDto.UnknownBaseGrainDto:
14573
+ return { text: '⚠ raw', title: diag || 'Base archive grain unknown — returned unreduced.' };
14574
+ case SeriesResolutionSignalDto.EmptyLadderDto:
14575
+ return { text: '⚠ no archive', title: diag || 'No resolvable archive for this series.' };
14576
+ default:
14577
+ return null;
14578
+ }
14579
+ }, /* @ts-ignore */
14580
+ ...(ngDevMode ? [{ debugName: "resolutionHint" }] : /* istanbul ignore next */ []));
14581
+ /**
14582
+ * Plain-language explanation shown when the user clicks the resolution warning — spells out why
14583
+ * fewer points were delivered and what to do about it, instead of the terse backend diagnostic.
14584
+ */
14585
+ resolutionExplanation = computed(() => {
14586
+ const s = this._resolutionSignal();
14587
+ if (!s || !this.resolutionHint())
14588
+ return null;
14589
+ const delivered = s.actualPoints ?? s.points;
14590
+ const requested = this._resolutionTarget();
14591
+ const ofReq = requested ? ` (the chart could show ~${requested})` : '';
14592
+ switch (s.signal) {
14593
+ case SeriesResolutionSignalDto.ResolutionLimitedDto:
14594
+ return `This chart auto-selects the coarsest stored resolution that still fits the view. `
14595
+ + `For this time range the finest matching rollup only provides ${delivered} point(s)${ofReq}, `
14596
+ + `so the line is drawn at a coarser resolution than the screen could show. The values are correct — `
14597
+ + `to see finer detail, narrow the time range or provision a finer rollup for this series.`;
14598
+ case SeriesResolutionSignalDto.NoSuitableRollupDto:
14599
+ return `No rollup matches this series' aggregation, so the raw archive was returned unreduced `
14600
+ + `(${delivered} points). Add a matching rollup to enable server-side reduction, or narrow the time range.`;
14601
+ case SeriesResolutionSignalDto.UnknownBaseGrainDto:
14602
+ return `The base archive's native resolution is undeclared, so the data was returned unreduced. `
14603
+ + `Set the archive's period/grain to enable resolution-aware selection.`;
14604
+ case SeriesResolutionSignalDto.EmptyLadderDto:
14605
+ return `No queryable archive was found for this series, so nothing could be plotted.`;
14606
+ default:
14607
+ return null;
14608
+ }
14609
+ }, /* @ts-ignore */
14610
+ ...(ngDevMode ? [{ debugName: "resolutionExplanation" }] : /* istanbul ignore next */ []));
14611
+ /** Toggles the click-through explanation panel for the resolution warning. */
14612
+ toggleResolutionInfo(event) {
14613
+ event?.stopPropagation();
14614
+ this._showResolutionInfo.update(v => !v);
14615
+ }
14616
+ /** Closes the resolution explanation panel (e.g. its close button). */
14617
+ closeResolutionInfo(event) {
14618
+ event?.stopPropagation();
14619
+ this._showResolutionInfo.set(false);
14620
+ }
14621
+ /**
14622
+ * Tooltip for the data-count badge: explains what `rows`/`pts` mean, and — when a resolution
14623
+ * warning is present — prefixes the diagnostic and prompts the click-through explanation.
14624
+ */
14625
+ badgeTitle(total) {
14626
+ const legend = `rows = data rows fetched (points × series) · pts = distinct time points plotted (totalCount ${total})`;
14627
+ const hint = this.resolutionHint();
14628
+ return hint ? `${hint.title}\nClick for details.\n\n${legend}` : legend;
14629
+ }
14343
14630
  data = computed(() => this._seriesData(), /* @ts-ignore */
14344
14631
  ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
14345
14632
  plotBands = computed(() => {
@@ -14475,6 +14762,25 @@ class LineChartWidgetComponent {
14475
14762
  this._error.set(null);
14476
14763
  try {
14477
14764
  const fieldFilter = this.convertFiltersToDto(this.config.filters);
14765
+ // Resolution-aware routing (AB#4290): let the server pick the archive/rollup for the visible
14766
+ // window + target point count, then downsample each source series against it. Requires a
14767
+ // stream-data query, a resolved time range, and a value field (which doubles as the series'
14768
+ // source path — the resolver matches it against the rollup's aggregation spec, case-insensitively).
14769
+ const timeArgs = this.stateService.resolveStreamDataTimeArgs(queryDataSource.ignoreTimeFilter);
14770
+ if (queryDataSource.resolutionAware && queryDataSource.queryFamily === 'streamData'
14771
+ && this.config.valueField && timeArgs?.from && timeArgs?.to) {
14772
+ const sourceRtIds = this.stateService.resolveStreamDataRtIds(queryDataSource.entitySelectorId);
14773
+ const { rows, signal, requestedPoints } = await this.loadResolutionAware(queryDataSource, timeArgs.from, timeArgs.to, sourceRtIds, fieldFilter ?? undefined);
14774
+ this._resolutionSignal.set(signal);
14775
+ this._resolutionTarget.set(requestedPoints);
14776
+ this.lastLimit = signal?.points ?? this.computeDownsampleLimit();
14777
+ this.processData(rows, true);
14778
+ this._dataInfo.set({ rows: rows.length, points: this._categories().length, total: rows.length });
14779
+ this._isLoading.set(false);
14780
+ return;
14781
+ }
14782
+ this._resolutionSignal.set(null);
14783
+ this._resolutionTarget.set(null);
14478
14784
  // queryFamily may be undefined for legacy widget configs — the executor
14479
14785
  // falls back to a one-time lookup by rtId. streamDataArgs is sent
14480
14786
  // unconditionally because the runtime path ignores it.
@@ -14498,9 +14804,101 @@ class LineChartWidgetComponent {
14498
14804
  console.error('Error loading Line Chart data:', err);
14499
14805
  this._error.set('Failed to load data');
14500
14806
  this._dataInfo.set(null);
14807
+ this._resolutionSignal.set(null);
14501
14808
  this._isLoading.set(false);
14502
14809
  }
14503
14810
  }
14811
+ /**
14812
+ * Resolution-aware routing (AB#4290): resolve the best archive/rollup for the window + target
14813
+ * point count, then downsample each source series against it. The transient downsampling groups
14814
+ * by bin (merging source rtIds), so this fans out one call per source rtId to keep each register
14815
+ * a separate line; each series' bins are reshaped onto the widget's configured value/series
14816
+ * fields so the shared {@link processData} pipeline renders them unchanged.
14817
+ */
14818
+ async loadResolutionAware(ds, from, to, sourceRtIds, fieldFilter) {
14819
+ const targetPoints = this.computeDownsampleLimit();
14820
+ const info = await this.queryExecutor.fetchQueryArchive(ds.queryRtId);
14821
+ if (!info) {
14822
+ throw new Error('Resolution-aware line chart: base archive not found for the selected query.');
14823
+ }
14824
+ // The Y-axis value field is the column being reduced, so it doubles as the resolver's
14825
+ // source path (matched case-insensitively against the rollup's aggregation spec).
14826
+ const sourcePath = this.config.valueField;
14827
+ const aggregation = (ds.requiredAggregation ?? 'SUM');
14828
+ const resolution = await this.queryExecutor.resolveSeriesQuery({
14829
+ baseArchiveRtId: info.archiveRtId,
14830
+ from,
14831
+ to,
14832
+ targetPoints,
14833
+ requiredAggregation: aggregation,
14834
+ sourcePath,
14835
+ rtIds: sourceRtIds && sourceRtIds.length > 0 ? sourceRtIds : undefined,
14836
+ obisFilter: ds.obisFilter || undefined,
14837
+ // Resolve calendar rollups in the board's zone so civil-day buckets match the
14838
+ // window (computed on the same zone by resolveCurrentTimeRange) — AB#4190.
14839
+ timeZone: this.stateService.resolveStreamDataTimeZone()
14840
+ });
14841
+ if (!resolution) {
14842
+ return { rows: [], signal: null, requestedPoints: targetPoints };
14843
+ }
14844
+ // Snap the query window to the resolver's effective-bucket grid. The downsampling engine only
14845
+ // aggregates a stored point into a bin when the bin width equals the data grain AND the window
14846
+ // start sits on that grid (from the epoch). An unaligned window — e.g. a relative "last N days"
14847
+ // filter ending at the current wall-clock time (…:42:54) — otherwise makes every bin miss the
14848
+ // hourly/interval data and yields an all-null (blank) chart. Aligning from + sizing to
14849
+ // points × bucket makes each bin land exactly on a stored point.
14850
+ let qFrom = from;
14851
+ let qTo = to;
14852
+ if (resolution.effectiveBucketMs > 0) {
14853
+ const bucket = resolution.effectiveBucketMs;
14854
+ const alignedFrom = Math.floor(from.getTime() / bucket) * bucket;
14855
+ qFrom = new Date(alignedFrom);
14856
+ qTo = new Date(alignedFrom + Math.max(1, resolution.points) * bucket);
14857
+ }
14858
+ // One downsampling call per source rtId → each register stays its own series (the transient
14859
+ // downsampling groups by bin, merging rtIds otherwise). With no source scope, a single merged
14860
+ // series is produced (labeled by the series-group field name).
14861
+ const seriesRtIds = sourceRtIds && sourceRtIds.length > 0 ? sourceRtIds : [undefined];
14862
+ const labels = info.ckTypeId
14863
+ ? await this.queryExecutor.fetchSeriesLabels(info.ckTypeId, sourceRtIds ?? [], this.config.seriesGroupField)
14864
+ : new Map();
14865
+ const rows = [];
14866
+ for (const rtId of seriesRtIds) {
14867
+ const seriesRows = await this.queryExecutor.downsampleByArchive({
14868
+ archiveRtId: resolution.archiveRtId,
14869
+ from: qFrom,
14870
+ to: qTo,
14871
+ limit: Math.max(1, resolution.points),
14872
+ sourcePath,
14873
+ aggregation: resolution.reducingFunction,
14874
+ rtIds: rtId ? [rtId] : undefined,
14875
+ fieldFilter
14876
+ });
14877
+ const label = rtId ? (labels.get(rtId) ?? rtId) : this.config.seriesGroupField;
14878
+ for (const r of seriesRows) {
14879
+ rows.push(this.reshapeResolutionRow(r, label));
14880
+ }
14881
+ }
14882
+ return { rows, signal: resolution, requestedPoints: targetPoints };
14883
+ }
14884
+ /**
14885
+ * Reshapes one downsampling bin onto the widget's configured value + series-group fields so the
14886
+ * shared {@link processData} path plots it. The transient row carries the reduced value under a
14887
+ * wire column name (e.g. `amountvalue_sum`) plus the bin `timestamp`; the value is re-emitted
14888
+ * under `valueField` and the series label under `seriesGroupField`.
14889
+ */
14890
+ reshapeResolutionRow(row, seriesLabel) {
14891
+ const valueCell = row.cells.find(c => c.attributePath.toLowerCase() !== 'timestamp');
14892
+ return {
14893
+ __typename: 'StreamDataQueryRow',
14894
+ rtId: row.rtId,
14895
+ timestamp: row.timestamp,
14896
+ cells: [
14897
+ { attributePath: this.config.valueField, value: valueCell?.value ?? null },
14898
+ { attributePath: this.config.seriesGroupField, value: seriesLabel }
14899
+ ]
14900
+ };
14901
+ }
14504
14902
  buildStreamDataArgs() {
14505
14903
  const ds = this.config.dataSource;
14506
14904
  const timeArgs = this.stateService.resolveStreamDataTimeArgs(ds.ignoreTimeFilter);
@@ -14688,8 +15086,8 @@ class LineChartWidgetComponent {
14688
15086
  const variables = this.stateService.getVariables();
14689
15087
  return this.variableService.convertToFieldFilterDto(filters, variables);
14690
15088
  }
14691
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: LineChartWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14692
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: LineChartWidgetComponent, isStandalone: true, selector: "mm-line-chart-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
15089
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LineChartWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15090
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: LineChartWidgetComponent, isStandalone: true, selector: "mm-line-chart-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
14693
15091
  <div class="line-chart-widget" [class.loading]="isLoading()" [class.error]="error()">
14694
15092
  @if (isNotConfigured()) {
14695
15093
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -14703,9 +15101,22 @@ class LineChartWidgetComponent {
14703
15101
  </div>
14704
15102
  } @else {
14705
15103
  @if (dataInfo(); as info) {
14706
- <span class="data-count" [title]="'Loaded rows · distinct category points (totalCount ' + info.total + ')'">
14707
- {{ info.rows }} rows · {{ info.points }} pts
14708
- </span>
15104
+ @if (config.showDataBadge !== false || resolutionHint()) {
15105
+ <span class="data-count" [class.warn]="!!resolutionHint()" [class.has-info]="!!resolutionHint()"
15106
+ [title]="badgeTitle(info.total)"
15107
+ (click)="resolutionHint() && toggleResolutionInfo($event)">
15108
+ {{ info.rows }} rows · {{ info.points }} pts@if (resolutionHint(); as hint) {<span class="rl-flag"> · {{ hint.text }}</span>}
15109
+ </span>
15110
+ }
15111
+ }
15112
+ @if (showResolutionInfo() && resolutionExplanation(); as msg) {
15113
+ <div class="resolution-info">
15114
+ <div class="ri-head">
15115
+ <span>Resolution-aware</span>
15116
+ <button type="button" class="ri-close" (click)="closeResolutionInfo($event)" aria-label="Close">✕</button>
15117
+ </div>
15118
+ <p class="ri-body">{{ msg }}</p>
15119
+ </div>
14709
15120
  }
14710
15121
  <kendo-chart class="chart-container" [plotArea]="{ background: 'transparent', margin: { top: 0, right: 0, bottom: 0, left: 0 } }">
14711
15122
  <kendo-chart-area [background]="'transparent'"></kendo-chart-area>
@@ -14805,9 +15216,9 @@ class LineChartWidgetComponent {
14805
15216
  </kendo-chart>
14806
15217
  }
14807
15218
  </div>
14808
- `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.line-chart-widget{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:8px;box-sizing:border-box;overflow:hidden}.data-count{position:absolute;top:4px;right:6px;z-index:2;max-width:calc(100% - 12px);padding:1px 7px;border-radius:9px;font-size:.7rem;line-height:1.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--kendo-color-on-app-surface, #6c757d);background:color-mix(in srgb,var(--kendo-color-app-surface, #888) 12%,transparent);pointer-events:none;-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums}.line-chart-widget.loading,.line-chart-widget.error{opacity:.7}.loading-indicator,.error-message{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.loading-indicator span{font-size:1.5rem;color:var(--kendo-color-subtle, #6c757d)}.error-message span{color:var(--kendo-color-error, #dc3545);font-size:.875rem}.chart-container{width:100%;height:100%}kendo-chart{width:100%;height:100%}.chart-tooltip{padding:4px 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ChartsModule }, { kind: "component", type: i1$7.ChartComponent, selector: "kendo-chart", inputs: ["pannable", "renderAs", "seriesColors", "subtitle", "title", "noData", "observeStyles", "transitions", "zoomable", "axisDefaults", "categoryAxis", "chartArea", "legend", "panes", "paneDefaults", "plotArea", "series", "seriesDefaults", "tooltip", "valueAxis", "xAxis", "yAxis", "resizeRateLimit", "popupSettings", "drilldownLevel"], outputs: ["axisLabelClick", "drag", "dragEnd", "dragStart", "legendItemHover", "legendItemLeave", "noteClick", "noteHover", "noteLeave", "paneRender", "plotAreaClick", "plotAreaHover", "plotAreaLeave", "render", "select", "selectEnd", "selectStart", "seriesClick", "drilldown", "seriesHover", "seriesOver", "seriesLeave", "zoom", "zoomEnd", "zoomStart", "legendItemClick", "drilldownLevelChange"], exportAs: ["kendoChart"] }, { kind: "directive", type: i1$7.SharedTooltipTemplateDirective, selector: "[kendoChartSharedTooltipTemplate]" }, { kind: "component", type: i1$7.CategoryAxisComponent, selector: "kendo-chart-category-axis" }, { kind: "component", type: i1$7.CategoryAxisItemComponent, selector: "kendo-chart-category-axis-item", inputs: ["autoBaseUnitSteps", "axisCrossingValue", "background", "baseUnit", "baseUnitStep", "categories", "color", "justified", "line", "majorGridLines", "majorTicks", "max", "maxDateGroups", "maxDivisions", "min", "minorGridLines", "minorTicks", "name", "pane", "plotBands", "reverse", "roundToBaseUnit", "startAngle", "type", "visible", "weekStartDay", "crosshair", "labels", "notes", "select", "title", "rangeLabels", "highlight"] }, { kind: "component", type: i1$7.CategoryAxisLabelsComponent, selector: "kendo-chart-category-axis-item-labels", inputs: ["background", "border", "color", "content", "culture", "dateFormats", "font", "format", "margin", "mirror", "padding", "position", "rotation", "skip", "step", "visible", "visual"] }, { kind: "component", type: i1$7.ChartAreaComponent, selector: "kendo-chart-area", inputs: ["background", "border", "height", "margin", "opacity", "width"] }, { kind: "component", type: i1$7.LegendComponent, selector: "kendo-chart-legend", inputs: ["align", "background", "border", "height", "labels", "margin", "offsetX", "offsetY", "orientation", "padding", "position", "reverse", "visible", "width", "markers", "spacing", "inactiveItems", "item", "title", "focusHighlight"] }, { kind: "component", type: i1$7.SeriesComponent, selector: "kendo-chart-series" }, { kind: "component", type: i1$7.SeriesItemComponent, selector: "kendo-chart-series-item", inputs: ["aggregate", "autoFit", "axis", "border", "categoryAxis", "categoryField", "closeField", "color", "colorField", "connectors", "currentField", "dashType", "data", "downColor", "downColorField", "drilldownField", "dynamicHeight", "dynamicSlope", "errorHighField", "errorLowField", "explodeField", "field", "fromField", "gap", "highField", "holeSize", "line", "lowField", "lowerField", "margin", "maxSize", "mean", "meanField", "median", "medianField", "minSize", "missingValues", "name", "neckRatio", "negativeColor", "negativeValues", "noteTextField", "opacity", "openField", "outliersField", "overlay", "padding", "q1Field", "q3Field", "segmentSpacing", "size", "sizeField", "spacing", "stack", "startAngle", "lineStyle", "summaryField", "target", "toField", "type", "upperField", "visible", "visibleInLegend", "visibleInLegendField", "visual", "width", "whiskers", "xAxis", "xErrorHighField", "xErrorLowField", "xField", "yAxis", "yErrorHighField", "yErrorLowField", "yField", "zIndex", "trendline", "for", "legendItem", "pattern", "patternField", "errorBars", "extremes", "highlight", "labels", "markers", "notes", "outliers", "tooltip"] }, { kind: "component", type: i1$7.TooltipComponent, selector: "kendo-chart-tooltip", inputs: ["background", "border", "color", "font", "format", "opacity", "padding", "shared", "visible"] }, { kind: "component", type: i1$7.ValueAxisComponent, selector: "kendo-chart-value-axis" }, { kind: "component", type: i1$7.ValueAxisItemComponent, selector: "kendo-chart-value-axis-item", inputs: ["axisCrossingValue", "background", "color", "line", "majorGridLines", "majorTicks", "majorUnit", "max", "min", "minorGridLines", "minorTicks", "minorUnit", "name", "narrowRange", "pane", "plotBands", "reverse", "type", "visible", "crosshair", "labels", "notes", "title"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
15219
+ `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.line-chart-widget{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:8px;box-sizing:border-box;overflow:hidden}.data-count{position:absolute;top:4px;right:6px;z-index:2;max-width:calc(100% - 12px);padding:1px 7px;border-radius:9px;font-size:.7rem;line-height:1.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--kendo-color-on-app-surface, #6c757d);background:color-mix(in srgb,var(--kendo-color-app-surface, #888) 12%,transparent);pointer-events:none;-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums}.data-count.warn{color:var(--kendo-color-warning, #b8860b);background:color-mix(in srgb,var(--kendo-color-warning, #f0ad4e) 16%,transparent)}.data-count.has-info{pointer-events:auto;cursor:pointer}.data-count .rl-flag{font-weight:600}.resolution-info{position:absolute;top:26px;right:6px;z-index:5;max-width:min(340px,calc(100% - 12px));padding:8px 10px;border-radius:6px;font-size:.75rem;line-height:1.4;color:var(--kendo-color-on-app-surface, #212529);background:var(--kendo-color-app-surface, #fff);border:1px solid color-mix(in srgb,var(--kendo-color-warning, #f0ad4e) 55%,transparent);box-shadow:0 4px 14px #0000002e;text-align:left}.resolution-info .ri-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:4px;font-weight:600;color:var(--kendo-color-warning, #b8860b)}.resolution-info .ri-close{border:none;background:transparent;cursor:pointer;font-size:.8rem;line-height:1;color:var(--kendo-color-subtle, #6c757d);padding:0 2px}.resolution-info .ri-body{margin:0}.line-chart-widget.loading,.line-chart-widget.error{opacity:.7}.loading-indicator,.error-message{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.loading-indicator span{font-size:1.5rem;color:var(--kendo-color-subtle, #6c757d)}.error-message span{color:var(--kendo-color-error, #dc3545);font-size:.875rem}.chart-container{width:100%;height:100%}kendo-chart{width:100%;height:100%}.chart-tooltip{padding:4px 8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ChartsModule }, { kind: "component", type: i1$7.ChartComponent, selector: "kendo-chart", inputs: ["pannable", "renderAs", "seriesColors", "subtitle", "title", "noData", "observeStyles", "transitions", "zoomable", "axisDefaults", "categoryAxis", "chartArea", "legend", "panes", "paneDefaults", "plotArea", "series", "seriesDefaults", "tooltip", "valueAxis", "xAxis", "yAxis", "resizeRateLimit", "popupSettings", "drilldownLevel"], outputs: ["axisLabelClick", "drag", "dragEnd", "dragStart", "legendItemHover", "legendItemLeave", "noteClick", "noteHover", "noteLeave", "paneRender", "plotAreaClick", "plotAreaHover", "plotAreaLeave", "render", "select", "selectEnd", "selectStart", "seriesClick", "drilldown", "seriesHover", "seriesOver", "seriesLeave", "zoom", "zoomEnd", "zoomStart", "legendItemClick", "drilldownLevelChange"], exportAs: ["kendoChart"] }, { kind: "directive", type: i1$7.SharedTooltipTemplateDirective, selector: "[kendoChartSharedTooltipTemplate]" }, { kind: "component", type: i1$7.CategoryAxisComponent, selector: "kendo-chart-category-axis" }, { kind: "component", type: i1$7.CategoryAxisItemComponent, selector: "kendo-chart-category-axis-item", inputs: ["autoBaseUnitSteps", "axisCrossingValue", "background", "baseUnit", "baseUnitStep", "categories", "color", "justified", "line", "majorGridLines", "majorTicks", "max", "maxDateGroups", "maxDivisions", "min", "minorGridLines", "minorTicks", "name", "pane", "plotBands", "reverse", "roundToBaseUnit", "startAngle", "type", "visible", "weekStartDay", "crosshair", "labels", "notes", "select", "title", "rangeLabels", "highlight"] }, { kind: "component", type: i1$7.CategoryAxisLabelsComponent, selector: "kendo-chart-category-axis-item-labels", inputs: ["background", "border", "color", "content", "culture", "dateFormats", "font", "format", "margin", "mirror", "padding", "position", "rotation", "skip", "step", "visible", "visual"] }, { kind: "component", type: i1$7.ChartAreaComponent, selector: "kendo-chart-area", inputs: ["background", "border", "height", "margin", "opacity", "width"] }, { kind: "component", type: i1$7.LegendComponent, selector: "kendo-chart-legend", inputs: ["align", "background", "border", "height", "labels", "margin", "offsetX", "offsetY", "orientation", "padding", "position", "reverse", "visible", "width", "markers", "spacing", "inactiveItems", "item", "title", "focusHighlight"] }, { kind: "component", type: i1$7.SeriesComponent, selector: "kendo-chart-series" }, { kind: "component", type: i1$7.SeriesItemComponent, selector: "kendo-chart-series-item", inputs: ["aggregate", "autoFit", "axis", "border", "categoryAxis", "categoryField", "closeField", "color", "colorField", "connectors", "currentField", "dashType", "data", "downColor", "downColorField", "drilldownField", "dynamicHeight", "dynamicSlope", "errorHighField", "errorLowField", "explodeField", "field", "fromField", "gap", "highField", "holeSize", "line", "lowField", "lowerField", "margin", "maxSize", "mean", "meanField", "median", "medianField", "minSize", "missingValues", "name", "neckRatio", "negativeColor", "negativeValues", "noteTextField", "opacity", "openField", "outliersField", "overlay", "padding", "q1Field", "q3Field", "segmentSpacing", "size", "sizeField", "spacing", "stack", "startAngle", "lineStyle", "summaryField", "target", "toField", "type", "upperField", "visible", "visibleInLegend", "visibleInLegendField", "visual", "width", "whiskers", "xAxis", "xErrorHighField", "xErrorLowField", "xField", "yAxis", "yErrorHighField", "yErrorLowField", "yField", "zIndex", "trendline", "for", "legendItem", "pattern", "patternField", "errorBars", "extremes", "highlight", "labels", "markers", "notes", "outliers", "tooltip"] }, { kind: "component", type: i1$7.TooltipComponent, selector: "kendo-chart-tooltip", inputs: ["background", "border", "color", "font", "format", "opacity", "padding", "shared", "visible"] }, { kind: "component", type: i1$7.ValueAxisComponent, selector: "kendo-chart-value-axis" }, { kind: "component", type: i1$7.ValueAxisItemComponent, selector: "kendo-chart-value-axis-item", inputs: ["axisCrossingValue", "background", "color", "line", "majorGridLines", "majorTicks", "majorUnit", "max", "min", "minorGridLines", "minorTicks", "minorUnit", "name", "narrowRange", "pane", "plotBands", "reverse", "type", "visible", "crosshair", "labels", "notes", "title"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
14809
15220
  }
14810
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: LineChartWidgetComponent, decorators: [{
15221
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LineChartWidgetComponent, decorators: [{
14811
15222
  type: Component,
14812
15223
  args: [{ selector: 'mm-line-chart-widget', standalone: true, imports: [
14813
15224
  CommonModule,
@@ -14827,9 +15238,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
14827
15238
  </div>
14828
15239
  } @else {
14829
15240
  @if (dataInfo(); as info) {
14830
- <span class="data-count" [title]="'Loaded rows · distinct category points (totalCount ' + info.total + ')'">
14831
- {{ info.rows }} rows · {{ info.points }} pts
14832
- </span>
15241
+ @if (config.showDataBadge !== false || resolutionHint()) {
15242
+ <span class="data-count" [class.warn]="!!resolutionHint()" [class.has-info]="!!resolutionHint()"
15243
+ [title]="badgeTitle(info.total)"
15244
+ (click)="resolutionHint() && toggleResolutionInfo($event)">
15245
+ {{ info.rows }} rows · {{ info.points }} pts@if (resolutionHint(); as hint) {<span class="rl-flag"> · {{ hint.text }}</span>}
15246
+ </span>
15247
+ }
15248
+ }
15249
+ @if (showResolutionInfo() && resolutionExplanation(); as msg) {
15250
+ <div class="resolution-info">
15251
+ <div class="ri-head">
15252
+ <span>Resolution-aware</span>
15253
+ <button type="button" class="ri-close" (click)="closeResolutionInfo($event)" aria-label="Close">✕</button>
15254
+ </div>
15255
+ <p class="ri-body">{{ msg }}</p>
15256
+ </div>
14833
15257
  }
14834
15258
  <kendo-chart class="chart-container" [plotArea]="{ background: 'transparent', margin: { top: 0, right: 0, bottom: 0, left: 0 } }">
14835
15259
  <kendo-chart-area [background]="'transparent'"></kendo-chart-area>
@@ -14929,7 +15353,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
14929
15353
  </kendo-chart>
14930
15354
  }
14931
15355
  </div>
14932
- `, changeDetection: ChangeDetectionStrategy.Eager, styles: [":host{display:block;width:100%;height:100%}.line-chart-widget{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:8px;box-sizing:border-box;overflow:hidden}.data-count{position:absolute;top:4px;right:6px;z-index:2;max-width:calc(100% - 12px);padding:1px 7px;border-radius:9px;font-size:.7rem;line-height:1.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--kendo-color-on-app-surface, #6c757d);background:color-mix(in srgb,var(--kendo-color-app-surface, #888) 12%,transparent);pointer-events:none;-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums}.line-chart-widget.loading,.line-chart-widget.error{opacity:.7}.loading-indicator,.error-message{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.loading-indicator span{font-size:1.5rem;color:var(--kendo-color-subtle, #6c757d)}.error-message span{color:var(--kendo-color-error, #dc3545);font-size:.875rem}.chart-container{width:100%;height:100%}kendo-chart{width:100%;height:100%}.chart-tooltip{padding:4px 8px}\n"] }]
15356
+ `, changeDetection: ChangeDetectionStrategy.Eager, styles: [":host{display:block;width:100%;height:100%}.line-chart-widget{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:8px;box-sizing:border-box;overflow:hidden}.data-count{position:absolute;top:4px;right:6px;z-index:2;max-width:calc(100% - 12px);padding:1px 7px;border-radius:9px;font-size:.7rem;line-height:1.5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--kendo-color-on-app-surface, #6c757d);background:color-mix(in srgb,var(--kendo-color-app-surface, #888) 12%,transparent);pointer-events:none;-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums}.data-count.warn{color:var(--kendo-color-warning, #b8860b);background:color-mix(in srgb,var(--kendo-color-warning, #f0ad4e) 16%,transparent)}.data-count.has-info{pointer-events:auto;cursor:pointer}.data-count .rl-flag{font-weight:600}.resolution-info{position:absolute;top:26px;right:6px;z-index:5;max-width:min(340px,calc(100% - 12px));padding:8px 10px;border-radius:6px;font-size:.75rem;line-height:1.4;color:var(--kendo-color-on-app-surface, #212529);background:var(--kendo-color-app-surface, #fff);border:1px solid color-mix(in srgb,var(--kendo-color-warning, #f0ad4e) 55%,transparent);box-shadow:0 4px 14px #0000002e;text-align:left}.resolution-info .ri-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:4px;font-weight:600;color:var(--kendo-color-warning, #b8860b)}.resolution-info .ri-close{border:none;background:transparent;cursor:pointer;font-size:.8rem;line-height:1;color:var(--kendo-color-subtle, #6c757d);padding:0 2px}.resolution-info .ri-body{margin:0}.line-chart-widget.loading,.line-chart-widget.error{opacity:.7}.loading-indicator,.error-message{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.loading-indicator span{font-size:1.5rem;color:var(--kendo-color-subtle, #6c757d)}.error-message span{color:var(--kendo-color-error, #dc3545);font-size:.875rem}.chart-container{width:100%;height:100%}kendo-chart{width:100%;height:100%}.chart-tooltip{padding:4px 8px}\n"] }]
14933
15357
  }], propDecorators: { config: [{
14934
15358
  type: Input
14935
15359
  }] } });
@@ -14950,6 +15374,8 @@ class LineChartConfigDialogComponent {
14950
15374
  initialQueryFamily;
14951
15375
  initialIgnoreTimeFilter;
14952
15376
  initialEntitySelectorId;
15377
+ initialResolutionAware;
15378
+ initialRequiredAggregation;
14953
15379
  initialChartType;
14954
15380
  initialCategoryField;
14955
15381
  initialSeriesGroupField;
@@ -14958,6 +15384,7 @@ class LineChartConfigDialogComponent {
14958
15384
  initialShowLegend;
14959
15385
  initialLegendPosition;
14960
15386
  initialShowMarkers;
15387
+ initialShowDataBadge;
14961
15388
  initialReferenceLines;
14962
15389
  initialFilters;
14963
15390
  // State
@@ -14972,6 +15399,18 @@ class LineChartConfigDialogComponent {
14972
15399
  ignoreTimeFilter = false;
14973
15400
  /** Asset-scope binding: id of the entity selector whose selection scopes the stream-data query. */
14974
15401
  entitySelectorId;
15402
+ /** Resolution-aware routing (AB#4290): auto-select the best archive/rollup before querying. */
15403
+ resolutionAware = false;
15404
+ /** Aggregation the series is reduced with (required when resolutionAware). */
15405
+ requiredAggregation = 'SUM';
15406
+ /** Aggregation options for the resolution-aware reducer dropdown. */
15407
+ aggregationOptions = [
15408
+ { value: 'SUM', label: 'Sum (additive, e.g. energy)' },
15409
+ { value: 'AVG', label: 'Average (instantaneous)' },
15410
+ { value: 'MAX', label: 'Max (e.g. demand)' },
15411
+ { value: 'MIN', label: 'Min' },
15412
+ { value: 'COUNT', label: 'Count' }
15413
+ ];
14975
15414
  /** Entity selectors available on the current MeshBoard (for the scope picker). */
14976
15415
  get availableEntitySelectors() {
14977
15416
  return this.stateService.getEntitySelectors();
@@ -15000,6 +15439,7 @@ class LineChartConfigDialogComponent {
15000
15439
  showLegend: true,
15001
15440
  legendPosition: 'right',
15002
15441
  showMarkers: false,
15442
+ showDataBadge: true,
15003
15443
  referenceLines: []
15004
15444
  };
15005
15445
  get isValid() {
@@ -15018,6 +15458,8 @@ class LineChartConfigDialogComponent {
15018
15458
  // Initialize form with initial values
15019
15459
  this.ignoreTimeFilter = this.initialIgnoreTimeFilter ?? false;
15020
15460
  this.entitySelectorId = this.initialEntitySelectorId;
15461
+ this.resolutionAware = this.initialResolutionAware ?? false;
15462
+ this.requiredAggregation = this.initialRequiredAggregation ?? 'SUM';
15021
15463
  this.form.chartType = this.initialChartType ?? 'line';
15022
15464
  this.form.categoryField = this.initialCategoryField ?? '';
15023
15465
  this.form.seriesGroupField = this.initialSeriesGroupField ?? '';
@@ -15026,6 +15468,7 @@ class LineChartConfigDialogComponent {
15026
15468
  this.form.showLegend = this.initialShowLegend ?? true;
15027
15469
  this.form.legendPosition = this.initialLegendPosition ?? 'right';
15028
15470
  this.form.showMarkers = this.initialShowMarkers ?? false;
15471
+ this.form.showDataBadge = this.initialShowDataBadge ?? true;
15029
15472
  this.form.referenceLines = this.initialReferenceLines ? [...this.initialReferenceLines] : [];
15030
15473
  // Initialize filters
15031
15474
  if (this.initialFilters && this.initialFilters.length > 0) {
@@ -15137,6 +15580,8 @@ class LineChartConfigDialogComponent {
15137
15580
  queryFamily: family,
15138
15581
  ignoreTimeFilter: this.ignoreTimeFilter,
15139
15582
  entitySelectorId: this.entitySelectorId,
15583
+ resolutionAware: this.resolutionAware || undefined,
15584
+ requiredAggregation: this.resolutionAware ? this.requiredAggregation : undefined,
15140
15585
  chartType: this.form.chartType,
15141
15586
  categoryField: this.form.categoryField,
15142
15587
  seriesGroupField: this.form.seriesGroupField,
@@ -15145,6 +15590,7 @@ class LineChartConfigDialogComponent {
15145
15590
  showLegend: this.form.showLegend,
15146
15591
  legendPosition: this.form.legendPosition,
15147
15592
  showMarkers: this.form.showMarkers,
15593
+ showDataBadge: this.form.showDataBadge,
15148
15594
  referenceLines: this.form.referenceLines.length > 0 ? this.form.referenceLines : undefined,
15149
15595
  filters: filtersDto
15150
15596
  };
@@ -15159,8 +15605,8 @@ class LineChartConfigDialogComponent {
15159
15605
  onCancel() {
15160
15606
  this.windowRef.close();
15161
15607
  }
15162
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: LineChartConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15163
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: LineChartConfigDialogComponent, isStandalone: true, selector: "mm-line-chart-config-dialog", inputs: { initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialChartType: "initialChartType", initialCategoryField: "initialCategoryField", initialSeriesGroupField: "initialSeriesGroupField", initialValueField: "initialValueField", initialUnitField: "initialUnitField", initialShowLegend: "initialShowLegend", initialLegendPosition: "initialLegendPosition", initialShowMarkers: "initialShowMarkers", initialReferenceLines: "initialReferenceLines", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
15608
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LineChartConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15609
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: LineChartConfigDialogComponent, isStandalone: true, selector: "mm-line-chart-config-dialog", inputs: { initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialResolutionAware: "initialResolutionAware", initialRequiredAggregation: "initialRequiredAggregation", initialChartType: "initialChartType", initialCategoryField: "initialCategoryField", initialSeriesGroupField: "initialSeriesGroupField", initialValueField: "initialValueField", initialUnitField: "initialUnitField", initialShowLegend: "initialShowLegend", initialLegendPosition: "initialLegendPosition", initialShowMarkers: "initialShowMarkers", initialShowDataBadge: "initialShowDataBadge", initialReferenceLines: "initialReferenceLines", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
15164
15610
  <div class="config-container">
15165
15611
 
15166
15612
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -15191,6 +15637,30 @@ class LineChartConfigDialogComponent {
15191
15637
  [selectors]="availableEntitySelectors"
15192
15638
  [(entitySelectorId)]="entitySelectorId">
15193
15639
  </mm-entity-selector-scope-picker>
15640
+
15641
+ @if (selectedQueryFamily === 'streamData') {
15642
+ <div class="form-field checkbox-field">
15643
+ <label>
15644
+ <input type="checkbox" [(ngModel)]="resolutionAware" kendoCheckBox />
15645
+ Resolution-aware archive selection
15646
+ </label>
15647
+ </div>
15648
+ <p class="field-hint">Picks the coarsest rollup that still yields the target point count for the visible time range, then downsamples against it. Each scoped source entity renders as its own line.</p>
15649
+
15650
+ @if (resolutionAware) {
15651
+ <div class="form-field">
15652
+ <label>Aggregation <span class="required">*</span></label>
15653
+ <kendo-dropdownlist
15654
+ [data]="aggregationOptions"
15655
+ [textField]="'label'"
15656
+ [valueField]="'value'"
15657
+ [valuePrimitive]="true"
15658
+ [(ngModel)]="requiredAggregation">
15659
+ </kendo-dropdownlist>
15660
+ <p class="field-hint">How the <strong>Value Field</strong> is reduced across buckets. Energy registers are additive → Sum. Never guessed.</p>
15661
+ </div>
15662
+ }
15663
+ }
15194
15664
  </div>
15195
15665
 
15196
15666
  <!-- Field Mapping Section -->
@@ -15332,6 +15802,13 @@ class LineChartConfigDialogComponent {
15332
15802
  Show Markers
15333
15803
  </label>
15334
15804
  </div>
15805
+
15806
+ <div class="form-field checkbox-field">
15807
+ <label>
15808
+ <input type="checkbox" [(ngModel)]="form.showDataBadge" kendoCheckBox />
15809
+ Show data badge
15810
+ </label>
15811
+ </div>
15335
15812
  </div>
15336
15813
 
15337
15814
  @if (form.showLegend) {
@@ -15376,7 +15853,7 @@ class LineChartConfigDialogComponent {
15376
15853
  </div>
15377
15854
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:20px;flex:1;overflow-y:auto;padding:16px;position:relative}.config-form.loading{pointer-events:none}.config-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.section-title{margin:0 0 16px;font-size:1rem;font-weight:600;color:var(--kendo-color-primary, #0d6efd)}.section-hint{margin:0 0 12px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}.form-field:last-child{margin-bottom:0}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.required{color:var(--kendo-color-error, #dc3545)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.chart-type-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}.radio-label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400}.form-row{display:flex;gap:24px;align-items:center}.checkbox-field{flex-direction:row;align-items:center;margin-bottom:0}.checkbox-field label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400}.column-item{display:flex;justify-content:space-between;gap:16px}.column-path{font-weight:500}.column-type{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-section{margin-top:8px}.form-section h4{margin:0 0 4px;font-size:.95rem;font-weight:600}.reference-line-row{display:flex;gap:8px;align-items:center;margin-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "directive", type: i3.RadioButtonDirective, selector: "input[kendoRadioButton]", inputs: ["size"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: QuerySelectorComponent, selector: "mm-query-selector", inputs: ["placeholder", "hint", "disabled", "acceptFamilies"], outputs: ["querySelected", "queriesLoaded"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
15378
15855
  }
15379
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: LineChartConfigDialogComponent, decorators: [{
15856
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LineChartConfigDialogComponent, decorators: [{
15380
15857
  type: Component,
15381
15858
  args: [{ selector: 'mm-line-chart-config-dialog', standalone: true, imports: [
15382
15859
  CommonModule,
@@ -15421,6 +15898,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
15421
15898
  [selectors]="availableEntitySelectors"
15422
15899
  [(entitySelectorId)]="entitySelectorId">
15423
15900
  </mm-entity-selector-scope-picker>
15901
+
15902
+ @if (selectedQueryFamily === 'streamData') {
15903
+ <div class="form-field checkbox-field">
15904
+ <label>
15905
+ <input type="checkbox" [(ngModel)]="resolutionAware" kendoCheckBox />
15906
+ Resolution-aware archive selection
15907
+ </label>
15908
+ </div>
15909
+ <p class="field-hint">Picks the coarsest rollup that still yields the target point count for the visible time range, then downsamples against it. Each scoped source entity renders as its own line.</p>
15910
+
15911
+ @if (resolutionAware) {
15912
+ <div class="form-field">
15913
+ <label>Aggregation <span class="required">*</span></label>
15914
+ <kendo-dropdownlist
15915
+ [data]="aggregationOptions"
15916
+ [textField]="'label'"
15917
+ [valueField]="'value'"
15918
+ [valuePrimitive]="true"
15919
+ [(ngModel)]="requiredAggregation">
15920
+ </kendo-dropdownlist>
15921
+ <p class="field-hint">How the <strong>Value Field</strong> is reduced across buckets. Energy registers are additive → Sum. Never guessed.</p>
15922
+ </div>
15923
+ }
15924
+ }
15424
15925
  </div>
15425
15926
 
15426
15927
  <!-- Field Mapping Section -->
@@ -15562,6 +16063,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
15562
16063
  Show Markers
15563
16064
  </label>
15564
16065
  </div>
16066
+
16067
+ <div class="form-field checkbox-field">
16068
+ <label>
16069
+ <input type="checkbox" [(ngModel)]="form.showDataBadge" kendoCheckBox />
16070
+ Show data badge
16071
+ </label>
16072
+ </div>
15565
16073
  </div>
15566
16074
 
15567
16075
  @if (form.showLegend) {
@@ -15618,6 +16126,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
15618
16126
  type: Input
15619
16127
  }], initialEntitySelectorId: [{
15620
16128
  type: Input
16129
+ }], initialResolutionAware: [{
16130
+ type: Input
16131
+ }], initialRequiredAggregation: [{
16132
+ type: Input
15621
16133
  }], initialChartType: [{
15622
16134
  type: Input
15623
16135
  }], initialCategoryField: [{
@@ -15634,6 +16146,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
15634
16146
  type: Input
15635
16147
  }], initialShowMarkers: [{
15636
16148
  type: Input
16149
+ }], initialShowDataBadge: [{
16150
+ type: Input
15637
16151
  }], initialReferenceLines: [{
15638
16152
  type: Input
15639
16153
  }], initialFilters: [{
@@ -16081,8 +16595,8 @@ class HeatmapWidgetComponent {
16081
16595
  const variables = this.stateService.getVariables();
16082
16596
  return this.variableService.convertToFieldFilterDto(filters, variables);
16083
16597
  }
16084
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: HeatmapWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16085
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: HeatmapWidgetComponent, isStandalone: true, selector: "mm-heatmap-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
16598
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: HeatmapWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16599
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: HeatmapWidgetComponent, isStandalone: true, selector: "mm-heatmap-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
16086
16600
  <div class="heatmap-widget" [class.loading]="isLoading()" [class.error]="error()">
16087
16601
  @if (isNotConfigured()) {
16088
16602
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -16141,7 +16655,7 @@ class HeatmapWidgetComponent {
16141
16655
  </div>
16142
16656
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.heatmap-widget{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:8px;box-sizing:border-box;overflow:hidden}.heatmap-widget.loading,.heatmap-widget.error{opacity:.7}.loading-indicator,.error-message{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.loading-indicator span{font-size:1.5rem;color:var(--kendo-color-subtle, #6c757d)}.error-message span{color:var(--kendo-color-error, #dc3545);font-size:.875rem}.chart-container{width:100%;height:100%}kendo-chart{width:100%;height:100%}.chart-tooltip{padding:4px 8px;color:#212529;background:#fff;border-radius:4px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ChartsModule }, { kind: "component", type: i1$7.ChartComponent, selector: "kendo-chart", inputs: ["pannable", "renderAs", "seriesColors", "subtitle", "title", "noData", "observeStyles", "transitions", "zoomable", "axisDefaults", "categoryAxis", "chartArea", "legend", "panes", "paneDefaults", "plotArea", "series", "seriesDefaults", "tooltip", "valueAxis", "xAxis", "yAxis", "resizeRateLimit", "popupSettings", "drilldownLevel"], outputs: ["axisLabelClick", "drag", "dragEnd", "dragStart", "legendItemHover", "legendItemLeave", "noteClick", "noteHover", "noteLeave", "paneRender", "plotAreaClick", "plotAreaHover", "plotAreaLeave", "render", "select", "selectEnd", "selectStart", "seriesClick", "drilldown", "seriesHover", "seriesOver", "seriesLeave", "zoom", "zoomEnd", "zoomStart", "legendItemClick", "drilldownLevelChange"], exportAs: ["kendoChart"] }, { kind: "component", type: i1$7.XAxisComponent, selector: "kendo-chart-x-axis" }, { kind: "component", type: i1$7.XAxisItemComponent, selector: "kendo-chart-x-axis-item", inputs: ["axisCrossingValue", "background", "baseUnit", "categories", "color", "line", "majorGridLines", "majorTicks", "majorUnit", "max", "min", "minorGridLines", "minorTicks", "minorUnit", "name", "narrowRange", "pane", "plotBands", "reverse", "startAngle", "type", "visible", "weekStartDay", "crosshair", "labels", "notes", "title"] }, { kind: "component", type: i1$7.XAxisLabelsComponent, selector: "kendo-chart-x-axis-item-labels", inputs: ["background", "border", "color", "content", "culture", "dateFormats", "font", "format", "margin", "mirror", "padding", "position", "rotation", "skip", "step", "visible", "visual"] }, { kind: "component", type: i1$7.YAxisComponent, selector: "kendo-chart-y-axis" }, { kind: "component", type: i1$7.YAxisItemComponent, selector: "kendo-chart-y-axis-item", inputs: ["axisCrossingValue", "background", "baseUnit", "categories", "color", "line", "majorGridLines", "majorTicks", "majorUnit", "max", "min", "minorGridLines", "minorTicks", "minorUnit", "name", "narrowRange", "pane", "plotBands", "reverse", "type", "visible", "crosshair", "labels", "notes", "title"] }, { kind: "directive", type: i1$7.SeriesTooltipTemplateDirective, selector: "[kendoChartSeriesTooltipTemplate]" }, { kind: "component", type: i1$7.LegendComponent, selector: "kendo-chart-legend", inputs: ["align", "background", "border", "height", "labels", "margin", "offsetX", "offsetY", "orientation", "padding", "position", "reverse", "visible", "width", "markers", "spacing", "inactiveItems", "item", "title", "focusHighlight"] }, { kind: "component", type: i1$7.SeriesComponent, selector: "kendo-chart-series" }, { kind: "component", type: i1$7.SeriesItemComponent, selector: "kendo-chart-series-item", inputs: ["aggregate", "autoFit", "axis", "border", "categoryAxis", "categoryField", "closeField", "color", "colorField", "connectors", "currentField", "dashType", "data", "downColor", "downColorField", "drilldownField", "dynamicHeight", "dynamicSlope", "errorHighField", "errorLowField", "explodeField", "field", "fromField", "gap", "highField", "holeSize", "line", "lowField", "lowerField", "margin", "maxSize", "mean", "meanField", "median", "medianField", "minSize", "missingValues", "name", "neckRatio", "negativeColor", "negativeValues", "noteTextField", "opacity", "openField", "outliersField", "overlay", "padding", "q1Field", "q3Field", "segmentSpacing", "size", "sizeField", "spacing", "stack", "startAngle", "lineStyle", "summaryField", "target", "toField", "type", "upperField", "visible", "visibleInLegend", "visibleInLegendField", "visual", "width", "whiskers", "xAxis", "xErrorHighField", "xErrorLowField", "xField", "yAxis", "yErrorHighField", "yErrorLowField", "yField", "zIndex", "trendline", "for", "legendItem", "pattern", "patternField", "errorBars", "extremes", "highlight", "labels", "markers", "notes", "outliers", "tooltip"] }, { kind: "component", type: i1$7.SeriesLabelsComponent, selector: "kendo-chart-series-item-labels", inputs: ["align", "background", "border", "color", "content", "ariaContent", "distance", "font", "format", "margin", "padding", "position", "rotation", "visible", "visual", "from", "to"] }, { kind: "component", type: i1$7.TooltipComponent, selector: "kendo-chart-tooltip", inputs: ["background", "border", "color", "font", "format", "opacity", "padding", "shared", "visible"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
16143
16657
  }
16144
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: HeatmapWidgetComponent, decorators: [{
16658
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: HeatmapWidgetComponent, decorators: [{
16145
16659
  type: Component,
16146
16660
  args: [{ selector: 'mm-heatmap-widget', standalone: true, imports: [
16147
16661
  CommonModule,
@@ -16462,8 +16976,8 @@ class HeatmapConfigDialogComponent {
16462
16976
  onCancel() {
16463
16977
  this.windowRef.close();
16464
16978
  }
16465
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: HeatmapConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16466
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: HeatmapConfigDialogComponent, isStandalone: true, selector: "mm-heatmap-config-dialog", inputs: { initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialDateField: "initialDateField", initialDateEndField: "initialDateEndField", initialValueField: "initialValueField", initialAggregation: "initialAggregation", initialColorScheme: "initialColorScheme", initialColorMode: "initialColorMode", initialThresholdTarget: "initialThresholdTarget", initialShowLegend: "initialShowLegend", initialLegendPosition: "initialLegendPosition", initialDecimalPlaces: "initialDecimalPlaces", initialCompactNumbers: "initialCompactNumbers", initialValueMultiplier: "initialValueMultiplier", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
16979
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: HeatmapConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16980
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: HeatmapConfigDialogComponent, isStandalone: true, selector: "mm-heatmap-config-dialog", inputs: { initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialIgnoreTimeFilter: "initialIgnoreTimeFilter", initialEntitySelectorId: "initialEntitySelectorId", initialDateField: "initialDateField", initialDateEndField: "initialDateEndField", initialValueField: "initialValueField", initialAggregation: "initialAggregation", initialColorScheme: "initialColorScheme", initialColorMode: "initialColorMode", initialThresholdTarget: "initialThresholdTarget", initialShowLegend: "initialShowLegend", initialLegendPosition: "initialLegendPosition", initialDecimalPlaces: "initialDecimalPlaces", initialCompactNumbers: "initialCompactNumbers", initialValueMultiplier: "initialValueMultiplier", initialFilters: "initialFilters" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
16467
16981
  <div class="config-container">
16468
16982
 
16469
16983
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -16724,7 +17238,7 @@ class HeatmapConfigDialogComponent {
16724
17238
  </div>
16725
17239
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:20px;flex:1;overflow-y:auto;padding:16px;position:relative}.config-form.loading{pointer-events:none}.config-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.section-title{margin:0 0 16px;font-size:1rem;font-weight:600;color:var(--kendo-color-primary, #0d6efd)}.section-hint{margin:0 0 12px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}.form-field:last-child{margin-bottom:0}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.required{color:var(--kendo-color-error, #dc3545)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.color-scheme-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}.radio-label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400}.color-scheme-preview{display:flex;align-items:center;gap:6px}.color-swatch{display:inline-block;width:16px;height:16px;border-radius:3px;border:1px solid var(--kendo-color-border, #dee2e6)}.form-row{display:flex;gap:24px}.checkbox-field{flex-direction:row;align-items:center}.checkbox-field label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400}.column-item{display:flex;justify-content:space-between;gap:16px}.column-path{font-weight:500}.column-type{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "directive", type: i3.RadioButtonDirective, selector: "input[kendoRadioButton]", inputs: ["size"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: QuerySelectorComponent, selector: "mm-query-selector", inputs: ["placeholder", "hint", "disabled", "acceptFamilies"], outputs: ["querySelected", "queriesLoaded"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
16726
17240
  }
16727
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: HeatmapConfigDialogComponent, decorators: [{
17241
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: HeatmapConfigDialogComponent, decorators: [{
16728
17242
  type: Component,
16729
17243
  args: [{ selector: 'mm-heatmap-config-dialog', standalone: true, imports: [
16730
17244
  CommonModule,
@@ -17229,10 +17743,10 @@ class StatsGridWidgetComponent {
17229
17743
  get gridColumns() {
17230
17744
  return this.config?.columns ?? 3;
17231
17745
  }
17232
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatsGridWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
17233
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: StatsGridWidgetComponent, isStandalone: true, selector: "mm-stats-grid-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"stats-grid\" [style.--grid-columns]=\"gridColumns\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n }\n @for (stat of statValues(); track stat.label) {\n <div class=\"stat-card\" [class]=\"stat.color\">\n @if (stat.isLoading) {\n <div class=\"stat-value loading\">...</div>\n } @else {\n <div class=\"stat-value\">{{ formatValue(stat) }}</div>\n }\n <div class=\"stat-label\">{{ stat.label }}</div>\n </div>\n }\n\n @if (error()) {\n <div class=\"stats-error\">\n {{ error() }}\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--mm-stat-mint-bg: rgba(152, 217, 194, .15);--mm-stat-mint-border: #98d9c2;--mm-stat-mint-text: #5ba88c;--mm-stat-mint-glow: none;--mm-stat-cyan-bg: rgba(91, 192, 190, .15);--mm-stat-cyan-border: #5bc0be;--mm-stat-cyan-text: #3a8a88;--mm-stat-cyan-glow: none;--mm-stat-violet-bg: rgba(155, 93, 229, .15);--mm-stat-violet-border: #9b5de5;--mm-stat-violet-text: #6b3baf;--mm-stat-violet-glow: none;--mm-stat-toffee-bg: rgba(244, 162, 97, .15);--mm-stat-toffee-border: #f4a261;--mm-stat-toffee-text: #c4723b;--mm-stat-toffee-glow: none;--mm-stat-lilac-bg: rgba(201, 177, 255, .15);--mm-stat-lilac-border: #c9b1ff;--mm-stat-lilac-text: #9981cf;--mm-stat-lilac-glow: none;--mm-stat-bubblegum-bg: rgba(255, 153, 200, .15);--mm-stat-bubblegum-border: #ff99c8;--mm-stat-bubblegum-text: #cf699a;--mm-stat-bubblegum-glow: none;--mm-stat-default-bg: rgba(108, 117, 125, .15);--mm-stat-default-border: #6c757d;--mm-stat-default-text: #4a5258;--mm-stat-default-glow: none}.stats-grid{display:grid;grid-template-columns:repeat(var(--grid-columns, 3),1fr);gap:12px;padding:8px;height:100%;align-content:center}.stat-card{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px 12px;border-radius:8px;background:#00000008;transition:transform .2s ease,box-shadow .2s ease}.stat-card:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0000001a}.stat-card.stat-mint{background:var(--mm-stat-mint-bg);border-left:4px solid var(--mm-stat-mint-border)}.stat-card.stat-mint .stat-value{color:var(--mm-stat-mint-text);text-shadow:var(--mm-stat-mint-glow)}.stat-card.stat-cyan{background:var(--mm-stat-cyan-bg);border-left:4px solid var(--mm-stat-cyan-border)}.stat-card.stat-cyan .stat-value{color:var(--mm-stat-cyan-text);text-shadow:var(--mm-stat-cyan-glow)}.stat-card.stat-violet{background:var(--mm-stat-violet-bg);border-left:4px solid var(--mm-stat-violet-border)}.stat-card.stat-violet .stat-value{color:var(--mm-stat-violet-text);text-shadow:var(--mm-stat-violet-glow)}.stat-card.stat-toffee{background:var(--mm-stat-toffee-bg);border-left:4px solid var(--mm-stat-toffee-border)}.stat-card.stat-toffee .stat-value{color:var(--mm-stat-toffee-text);text-shadow:var(--mm-stat-toffee-glow)}.stat-card.stat-lilac{background:var(--mm-stat-lilac-bg);border-left:4px solid var(--mm-stat-lilac-border)}.stat-card.stat-lilac .stat-value{color:var(--mm-stat-lilac-text);text-shadow:var(--mm-stat-lilac-glow)}.stat-card.stat-bubblegum{background:var(--mm-stat-bubblegum-bg);border-left:4px solid var(--mm-stat-bubblegum-border)}.stat-card.stat-bubblegum .stat-value{color:var(--mm-stat-bubblegum-text);text-shadow:var(--mm-stat-bubblegum-glow)}.stat-card.stat-default{background:var(--mm-stat-default-bg);border-left:4px solid var(--mm-stat-default-border)}.stat-card.stat-default .stat-value{color:var(--mm-stat-default-text);text-shadow:var(--mm-stat-default-glow)}.stat-value{font-size:2rem;font-weight:700;line-height:1.2;text-align:center}.stat-value.loading{opacity:.5;animation:pulse 1.5s ease-in-out infinite}.stat-label{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:var(--kendo-color-subtle, #6c757d);margin-top:4px;text-align:center}.stats-error{grid-column:1/-1;text-align:center;padding:16px;color:var(--kendo-color-error, #dc3545);font-size:.875rem}@keyframes pulse{0%,to{opacity:.5}50%{opacity:.3}}@media(max-width:768px){.stats-grid{grid-template-columns:repeat(2,1fr);gap:8px}.stat-value{font-size:1.5rem}.stat-label{font-size:.65rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
17746
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatsGridWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
17747
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: StatsGridWidgetComponent, isStandalone: true, selector: "mm-stats-grid-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"stats-grid\" [style.--grid-columns]=\"gridColumns\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n }\n @for (stat of statValues(); track stat.label) {\n <div class=\"stat-card\" [class]=\"stat.color\">\n @if (stat.isLoading) {\n <div class=\"stat-value loading\">...</div>\n } @else {\n <div class=\"stat-value\">{{ formatValue(stat) }}</div>\n }\n <div class=\"stat-label\">{{ stat.label }}</div>\n </div>\n }\n\n @if (error()) {\n <div class=\"stats-error\">\n {{ error() }}\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--mm-stat-mint-bg: rgba(152, 217, 194, .15);--mm-stat-mint-border: #98d9c2;--mm-stat-mint-text: #5ba88c;--mm-stat-mint-glow: none;--mm-stat-cyan-bg: rgba(91, 192, 190, .15);--mm-stat-cyan-border: #5bc0be;--mm-stat-cyan-text: #3a8a88;--mm-stat-cyan-glow: none;--mm-stat-violet-bg: rgba(155, 93, 229, .15);--mm-stat-violet-border: #9b5de5;--mm-stat-violet-text: #6b3baf;--mm-stat-violet-glow: none;--mm-stat-toffee-bg: rgba(244, 162, 97, .15);--mm-stat-toffee-border: #f4a261;--mm-stat-toffee-text: #c4723b;--mm-stat-toffee-glow: none;--mm-stat-lilac-bg: rgba(201, 177, 255, .15);--mm-stat-lilac-border: #c9b1ff;--mm-stat-lilac-text: #9981cf;--mm-stat-lilac-glow: none;--mm-stat-bubblegum-bg: rgba(255, 153, 200, .15);--mm-stat-bubblegum-border: #ff99c8;--mm-stat-bubblegum-text: #cf699a;--mm-stat-bubblegum-glow: none;--mm-stat-default-bg: rgba(108, 117, 125, .15);--mm-stat-default-border: #6c757d;--mm-stat-default-text: #4a5258;--mm-stat-default-glow: none}.stats-grid{display:grid;grid-template-columns:repeat(var(--grid-columns, 3),1fr);gap:12px;padding:8px;height:100%;align-content:center}.stat-card{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px 12px;border-radius:8px;background:#00000008;transition:transform .2s ease,box-shadow .2s ease}.stat-card:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0000001a}.stat-card.stat-mint{background:var(--mm-stat-mint-bg);border-left:4px solid var(--mm-stat-mint-border)}.stat-card.stat-mint .stat-value{color:var(--mm-stat-mint-text);text-shadow:var(--mm-stat-mint-glow)}.stat-card.stat-cyan{background:var(--mm-stat-cyan-bg);border-left:4px solid var(--mm-stat-cyan-border)}.stat-card.stat-cyan .stat-value{color:var(--mm-stat-cyan-text);text-shadow:var(--mm-stat-cyan-glow)}.stat-card.stat-violet{background:var(--mm-stat-violet-bg);border-left:4px solid var(--mm-stat-violet-border)}.stat-card.stat-violet .stat-value{color:var(--mm-stat-violet-text);text-shadow:var(--mm-stat-violet-glow)}.stat-card.stat-toffee{background:var(--mm-stat-toffee-bg);border-left:4px solid var(--mm-stat-toffee-border)}.stat-card.stat-toffee .stat-value{color:var(--mm-stat-toffee-text);text-shadow:var(--mm-stat-toffee-glow)}.stat-card.stat-lilac{background:var(--mm-stat-lilac-bg);border-left:4px solid var(--mm-stat-lilac-border)}.stat-card.stat-lilac .stat-value{color:var(--mm-stat-lilac-text);text-shadow:var(--mm-stat-lilac-glow)}.stat-card.stat-bubblegum{background:var(--mm-stat-bubblegum-bg);border-left:4px solid var(--mm-stat-bubblegum-border)}.stat-card.stat-bubblegum .stat-value{color:var(--mm-stat-bubblegum-text);text-shadow:var(--mm-stat-bubblegum-glow)}.stat-card.stat-default{background:var(--mm-stat-default-bg);border-left:4px solid var(--mm-stat-default-border)}.stat-card.stat-default .stat-value{color:var(--mm-stat-default-text);text-shadow:var(--mm-stat-default-glow)}.stat-value{font-size:2rem;font-weight:700;line-height:1.2;text-align:center}.stat-value.loading{opacity:.5;animation:pulse 1.5s ease-in-out infinite}.stat-label{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:var(--kendo-color-subtle, #6c757d);margin-top:4px;text-align:center}.stats-error{grid-column:1/-1;text-align:center;padding:16px;color:var(--kendo-color-error, #dc3545);font-size:.875rem}@keyframes pulse{0%,to{opacity:.5}50%{opacity:.3}}@media(max-width:768px){.stats-grid{grid-template-columns:repeat(2,1fr);gap:8px}.stat-value{font-size:1.5rem}.stat-label{font-size:.65rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
17234
17748
  }
17235
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatsGridWidgetComponent, decorators: [{
17749
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatsGridWidgetComponent, decorators: [{
17236
17750
  type: Component,
17237
17751
  args: [{ selector: 'mm-stats-grid-widget', standalone: true, imports: [CommonModule, WidgetNotConfiguredComponent], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"stats-grid\" [style.--grid-columns]=\"gridColumns\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n }\n @for (stat of statValues(); track stat.label) {\n <div class=\"stat-card\" [class]=\"stat.color\">\n @if (stat.isLoading) {\n <div class=\"stat-value loading\">...</div>\n } @else {\n <div class=\"stat-value\">{{ formatValue(stat) }}</div>\n }\n <div class=\"stat-label\">{{ stat.label }}</div>\n </div>\n }\n\n @if (error()) {\n <div class=\"stats-error\">\n {{ error() }}\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--mm-stat-mint-bg: rgba(152, 217, 194, .15);--mm-stat-mint-border: #98d9c2;--mm-stat-mint-text: #5ba88c;--mm-stat-mint-glow: none;--mm-stat-cyan-bg: rgba(91, 192, 190, .15);--mm-stat-cyan-border: #5bc0be;--mm-stat-cyan-text: #3a8a88;--mm-stat-cyan-glow: none;--mm-stat-violet-bg: rgba(155, 93, 229, .15);--mm-stat-violet-border: #9b5de5;--mm-stat-violet-text: #6b3baf;--mm-stat-violet-glow: none;--mm-stat-toffee-bg: rgba(244, 162, 97, .15);--mm-stat-toffee-border: #f4a261;--mm-stat-toffee-text: #c4723b;--mm-stat-toffee-glow: none;--mm-stat-lilac-bg: rgba(201, 177, 255, .15);--mm-stat-lilac-border: #c9b1ff;--mm-stat-lilac-text: #9981cf;--mm-stat-lilac-glow: none;--mm-stat-bubblegum-bg: rgba(255, 153, 200, .15);--mm-stat-bubblegum-border: #ff99c8;--mm-stat-bubblegum-text: #cf699a;--mm-stat-bubblegum-glow: none;--mm-stat-default-bg: rgba(108, 117, 125, .15);--mm-stat-default-border: #6c757d;--mm-stat-default-text: #4a5258;--mm-stat-default-glow: none}.stats-grid{display:grid;grid-template-columns:repeat(var(--grid-columns, 3),1fr);gap:12px;padding:8px;height:100%;align-content:center}.stat-card{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px 12px;border-radius:8px;background:#00000008;transition:transform .2s ease,box-shadow .2s ease}.stat-card:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0000001a}.stat-card.stat-mint{background:var(--mm-stat-mint-bg);border-left:4px solid var(--mm-stat-mint-border)}.stat-card.stat-mint .stat-value{color:var(--mm-stat-mint-text);text-shadow:var(--mm-stat-mint-glow)}.stat-card.stat-cyan{background:var(--mm-stat-cyan-bg);border-left:4px solid var(--mm-stat-cyan-border)}.stat-card.stat-cyan .stat-value{color:var(--mm-stat-cyan-text);text-shadow:var(--mm-stat-cyan-glow)}.stat-card.stat-violet{background:var(--mm-stat-violet-bg);border-left:4px solid var(--mm-stat-violet-border)}.stat-card.stat-violet .stat-value{color:var(--mm-stat-violet-text);text-shadow:var(--mm-stat-violet-glow)}.stat-card.stat-toffee{background:var(--mm-stat-toffee-bg);border-left:4px solid var(--mm-stat-toffee-border)}.stat-card.stat-toffee .stat-value{color:var(--mm-stat-toffee-text);text-shadow:var(--mm-stat-toffee-glow)}.stat-card.stat-lilac{background:var(--mm-stat-lilac-bg);border-left:4px solid var(--mm-stat-lilac-border)}.stat-card.stat-lilac .stat-value{color:var(--mm-stat-lilac-text);text-shadow:var(--mm-stat-lilac-glow)}.stat-card.stat-bubblegum{background:var(--mm-stat-bubblegum-bg);border-left:4px solid var(--mm-stat-bubblegum-border)}.stat-card.stat-bubblegum .stat-value{color:var(--mm-stat-bubblegum-text);text-shadow:var(--mm-stat-bubblegum-glow)}.stat-card.stat-default{background:var(--mm-stat-default-bg);border-left:4px solid var(--mm-stat-default-border)}.stat-card.stat-default .stat-value{color:var(--mm-stat-default-text);text-shadow:var(--mm-stat-default-glow)}.stat-value{font-size:2rem;font-weight:700;line-height:1.2;text-align:center}.stat-value.loading{opacity:.5;animation:pulse 1.5s ease-in-out infinite}.stat-label{font-size:.75rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:var(--kendo-color-subtle, #6c757d);margin-top:4px;text-align:center}.stats-error{grid-column:1/-1;text-align:center;padding:16px;color:var(--kendo-color-error, #dc3545);font-size:.875rem}@keyframes pulse{0%,to{opacity:.5}50%{opacity:.3}}@media(max-width:768px){.stats-grid{grid-template-columns:repeat(2,1fr);gap:8px}.stat-value{font-size:1.5rem}.stat-label{font-size:.65rem}}\n"] }]
17238
17752
  }], propDecorators: { config: [{
@@ -17345,8 +17859,8 @@ class PersistentQueryCellEditorComponent {
17345
17859
  this.isLoading = false;
17346
17860
  }
17347
17861
  }
17348
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PersistentQueryCellEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
17349
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: PersistentQueryCellEditorComponent, isStandalone: true, selector: "mm-persistent-query-cell-editor", inputs: { initialSource: "initialSource", selectors: "selectors" }, outputs: { sourceChange: "sourceChange" }, ngImport: i0, template: `
17862
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: PersistentQueryCellEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
17863
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: PersistentQueryCellEditorComponent, isStandalone: true, selector: "mm-persistent-query-cell-editor", inputs: { initialSource: "initialSource", selectors: "selectors" }, outputs: { sourceChange: "sourceChange" }, ngImport: i0, template: `
17350
17864
  <div class="pq-editor">
17351
17865
  <div class="pq-field">
17352
17866
  <label>Persistent Query <span class="required">*</span></label>
@@ -17409,7 +17923,7 @@ class PersistentQueryCellEditorComponent {
17409
17923
  </div>
17410
17924
  `, isInline: true, styles: [".pq-editor{display:flex;flex-direction:column;gap:8px}.pq-field{display:flex;flex-direction:column;gap:4px}.pq-field label{font-weight:600;font-size:.85rem}.required{color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
17411
17925
  }
17412
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PersistentQueryCellEditorComponent, decorators: [{
17926
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: PersistentQueryCellEditorComponent, decorators: [{
17413
17927
  type: Component,
17414
17928
  args: [{ selector: 'mm-persistent-query-cell-editor', standalone: true, imports: [CommonModule, FormsModule, InputsModule, DropDownsModule, SdTimeFilterToggleComponent, EntitySelectorScopePickerComponent], changeDetection: ChangeDetectionStrategy.Eager, template: `
17415
17929
  <div class="pq-editor">
@@ -17608,8 +18122,8 @@ class StatsGridConfigDialogComponent {
17608
18122
  onCancel() {
17609
18123
  this.windowRef.close();
17610
18124
  }
17611
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatsGridConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
17612
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: StatsGridConfigDialogComponent, isStandalone: true, selector: "mm-stats-grid-config-dialog", inputs: { initialStats: "initialStats", initialQueries: "initialQueries", initialColumns: "initialColumns" }, ngImport: i0, template: `
18125
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatsGridConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18126
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: StatsGridConfigDialogComponent, isStandalone: true, selector: "mm-stats-grid-config-dialog", inputs: { initialStats: "initialStats", initialQueries: "initialQueries", initialColumns: "initialColumns" }, ngImport: i0, template: `
17613
18127
  <div class="config-container">
17614
18128
 
17615
18129
  <div class="config-form">
@@ -17770,7 +18284,7 @@ class StatsGridConfigDialogComponent {
17770
18284
  </div>
17771
18285
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:20px;padding:16px;flex:1;overflow-y:auto}.form-field{display:flex;flex-direction:column;gap:6px}.form-field.flex-1{flex:1}.form-field.flex-2{flex:2}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.section-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.section-header h4{margin:0;font-size:.95rem;color:var(--kendo-color-primary, #0d6efd)}.form-row{display:flex;gap:16px}.required{color:var(--kendo-color-error, #dc3545)}.empty-state{text-align:center;padding:24px;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.stat-item{padding:16px;margin-bottom:12px;background:var(--kendo-color-surface, #ffffff);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.stat-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.stat-number{font-weight:600;color:var(--kendo-color-primary, #0d6efd)}.stat-form{display:flex;flex-direction:column;gap:12px}.color-item{display:flex;align-items:center;gap:8px}.color-swatch{width:16px;height:16px;border-radius:3px;border:1px solid rgba(0,0,0,.1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "directive", type: i4.ValueTemplateDirective, selector: "[kendoDropDownListValueTemplate],[kendoDropDownTreeValueTemplate]" }, { kind: "component", type: PersistentQueryCellEditorComponent, selector: "mm-persistent-query-cell-editor", inputs: ["initialSource", "selectors"], outputs: ["sourceChange"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
17772
18286
  }
17773
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatsGridConfigDialogComponent, decorators: [{
18287
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatsGridConfigDialogComponent, decorators: [{
17774
18288
  type: Component,
17775
18289
  args: [{ selector: 'mm-stats-grid-config-dialog', standalone: true, imports: [
17776
18290
  CommonModule,
@@ -18044,10 +18558,10 @@ class StatusIndicatorWidgetComponent {
18044
18558
  return this.config.falseColor ?? '#ef4444';
18045
18559
  }
18046
18560
  }
18047
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatusIndicatorWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18048
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: StatusIndicatorWidgetComponent, isStandalone: true, selector: "mm-status-indicator-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"status-indicator\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else {\n <div class=\"status-badge\" [style.background-color]=\"statusColor\">\n <span class=\"status-text\">{{ statusLabel }}</span>\n </div>\n\n @if (error()) {\n <div class=\"status-error\">\n {{ error() }}\n </div>\n }\n }\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.status-indicator{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;padding:16px}.status-indicator.loading .status-badge{opacity:.6;animation:pulse 1.5s ease-in-out infinite}.status-indicator.error .status-badge{background-color:var(--kendo-color-error, #dc3545)!important}.status-badge{display:inline-flex;align-items:center;justify-content:center;padding:8px 24px;border-radius:24px;min-width:120px;transition:background-color .3s ease,opacity .3s ease}.status-text{font-size:.875rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2)}.status-error{margin-top:8px;font-size:.75rem;color:var(--kendo-color-error, #dc3545);text-align:center}@keyframes pulse{0%,to{opacity:.6}50%{opacity:.3}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
18561
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatusIndicatorWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: StatusIndicatorWidgetComponent, isStandalone: true, selector: "mm-status-indicator-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"status-indicator\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else {\n <div class=\"status-badge\" [style.background-color]=\"statusColor\">\n <span class=\"status-text\">{{ statusLabel }}</span>\n </div>\n\n @if (error()) {\n <div class=\"status-error\">\n {{ error() }}\n </div>\n }\n }\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.status-indicator{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;padding:16px}.status-indicator.loading .status-badge{opacity:.6;animation:pulse 1.5s ease-in-out infinite}.status-indicator.error .status-badge{background-color:var(--kendo-color-error, #dc3545)!important}.status-badge{display:inline-flex;align-items:center;justify-content:center;padding:8px 24px;border-radius:24px;min-width:120px;transition:background-color .3s ease,opacity .3s ease}.status-text{font-size:.875rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2)}.status-error{margin-top:8px;font-size:.75rem;color:var(--kendo-color-error, #dc3545);text-align:center}@keyframes pulse{0%,to{opacity:.6}50%{opacity:.3}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
18049
18563
  }
18050
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatusIndicatorWidgetComponent, decorators: [{
18564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatusIndicatorWidgetComponent, decorators: [{
18051
18565
  type: Component,
18052
18566
  args: [{ selector: 'mm-status-indicator-widget', standalone: true, imports: [CommonModule, WidgetNotConfiguredComponent], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"status-indicator\" [class.loading]=\"isLoading()\" [class.error]=\"error()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else {\n <div class=\"status-badge\" [style.background-color]=\"statusColor\">\n <span class=\"status-text\">{{ statusLabel }}</span>\n </div>\n\n @if (error()) {\n <div class=\"status-error\">\n {{ error() }}\n </div>\n }\n }\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.status-indicator{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;padding:16px}.status-indicator.loading .status-badge{opacity:.6;animation:pulse 1.5s ease-in-out infinite}.status-indicator.error .status-badge{background-color:var(--kendo-color-error, #dc3545)!important}.status-badge{display:inline-flex;align-items:center;justify-content:center;padding:8px 24px;border-radius:24px;min-width:120px;transition:background-color .3s ease,opacity .3s ease}.status-text{font-size:.875rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2)}.status-error{margin-top:8px;font-size:.75rem;color:var(--kendo-color-error, #dc3545);text-align:center}@keyframes pulse{0%,to{opacity:.6}50%{opacity:.3}}\n"] }]
18053
18567
  }], propDecorators: { config: [{
@@ -18119,8 +18633,8 @@ class StatusIndicatorConfigDialogComponent {
18119
18633
  onCancel() {
18120
18634
  this.windowRef.close();
18121
18635
  }
18122
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatusIndicatorConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18123
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: StatusIndicatorConfigDialogComponent, isStandalone: true, selector: "mm-status-indicator-config-dialog", inputs: { initialCallType: "initialCallType", initialModelName: "initialModelName", initialServiceType: "initialServiceType", initialTrueLabel: "initialTrueLabel", initialFalseLabel: "initialFalseLabel", initialTrueColor: "initialTrueColor", initialFalseColor: "initialFalseColor" }, ngImport: i0, template: `
18636
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatusIndicatorConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18637
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: StatusIndicatorConfigDialogComponent, isStandalone: true, selector: "mm-status-indicator-config-dialog", inputs: { initialCallType: "initialCallType", initialModelName: "initialModelName", initialServiceType: "initialServiceType", initialTrueLabel: "initialTrueLabel", initialFalseLabel: "initialFalseLabel", initialTrueColor: "initialTrueColor", initialFalseColor: "initialFalseColor" }, ngImport: i0, template: `
18124
18638
  <div class="config-container">
18125
18639
 
18126
18640
  <div class="config-form">
@@ -18224,7 +18738,7 @@ class StatusIndicatorConfigDialogComponent {
18224
18738
  </div>
18225
18739
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:20px;padding:16px}.form-field{display:flex;flex-direction:column;gap:6px}.form-field.flex-1{flex:1}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.form-section h4{margin:0 0 16px;font-size:.95rem;color:var(--kendo-color-primary, #0d6efd)}.form-row{display:flex;gap:16px}.required{color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.ColorPickerComponent, selector: "kendo-colorpicker", inputs: ["views", "view", "adaptiveMode", "activeView", "readonly", "disabled", "format", "value", "popupSettings", "paletteSettings", "gradientSettings", "icon", "iconClass", "svgIcon", "adaptiveTitle", "adaptiveSubtitle", "clearButton", "tabindex", "preview", "actionsLayout", "size", "rounded", "fillMode"], outputs: ["valueChange", "open", "close", "focus", "blur", "cancel", "activeColorClick", "clearButtonClick", "activeViewChange"], exportAs: ["kendoColorPicker"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
18226
18740
  }
18227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatusIndicatorConfigDialogComponent, decorators: [{
18741
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatusIndicatorConfigDialogComponent, decorators: [{
18228
18742
  type: Component,
18229
18743
  args: [{ selector: 'mm-status-indicator-config-dialog', standalone: true, imports: [
18230
18744
  CommonModule,
@@ -18475,10 +18989,10 @@ class ServiceHealthWidgetComponent {
18475
18989
  get isClickable() {
18476
18990
  return !!this.config.navigateOnClick && !!this.config.detailRoute;
18477
18991
  }
18478
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ServiceHealthWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18479
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: ServiceHealthWidgetComponent, isStandalone: true, selector: "mm-service-health-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "@if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n} @else {\n <div\n class=\"service-health\"\n [class.clickable]=\"isClickable\"\n [class.healthy]=\"healthStatus() === 'healthy'\"\n [class.unhealthy]=\"healthStatus() === 'unhealthy'\"\n [class.loading]=\"healthStatus() === 'loading'\"\n (click)=\"onClick()\">\n\n <div class=\"health-indicator\">\n <div class=\"pulse-ring\" [class.pulse-active]=\"showPulse\"></div>\n <div class=\"health-dot\" [class.pulse-dot]=\"showPulse\"></div>\n </div>\n\n <div class=\"health-info\">\n <div class=\"service-name\">{{ serviceName }}</div>\n <div class=\"health-status\">{{ statusLabel }}</div>\n @if (lastChecked()) {\n <div class=\"last-checked\">\n Last checked: {{ lastChecked() | date:'HH:mm:ss' }}\n </div>\n }\n </div>\n\n @if (error()) {\n <div class=\"health-error\">\n {{ error() }}\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%}.service-health{display:flex;align-items:center;gap:16px;padding:16px;height:100%;border-radius:8px;background:#00000008;transition:background .3s ease,box-shadow .3s ease}.service-health.clickable{cursor:pointer}.service-health.clickable:hover{background:#0000000f;box-shadow:0 2px 8px #0000001a}.service-health.healthy .health-dot{background:#10b981}.service-health.healthy .pulse-ring.pulse-active{border-color:#10b981}.service-health.unhealthy .health-dot{background:#ef4444}.service-health.unhealthy .pulse-ring{border-color:#ef4444}.service-health.loading .health-dot{background:#6b7280;animation:pulse-loading 1.5s ease-in-out infinite}.health-indicator{position:relative;width:48px;height:48px;display:flex;align-items:center;justify-content:center}.health-dot{width:16px;height:16px;border-radius:50%;background:#6b7280;z-index:1;transition:background .3s ease}.health-dot.pulse-dot{animation:pulse-dot 2s ease-in-out infinite}.pulse-ring{position:absolute;width:32px;height:32px;border:2px solid transparent;border-radius:50%;opacity:0}.pulse-ring.pulse-active{animation:pulse-ring 2s ease-out infinite}.health-info{flex:1;min-width:0}.service-name{font-size:1rem;font-weight:600;color:var(--kendo-color-on-app-surface, #1f2937);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.health-status{font-size:.875rem;font-weight:500;color:var(--kendo-color-subtle, #6b7280)}.healthy .health-status{color:#10b981}.unhealthy .health-status{color:#ef4444}.last-checked{font-size:.7rem;color:var(--kendo-color-subtle, #9ca3af);margin-top:4px}.health-error{font-size:.75rem;color:var(--kendo-color-error, #dc3545);margin-top:8px}@keyframes pulse-ring{0%{transform:scale(.8);opacity:.8}50%{transform:scale(1.2);opacity:.4}to{transform:scale(1.5);opacity:0}}@keyframes pulse-dot{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.1);opacity:.8}}@keyframes pulse-loading{0%,to{opacity:1}50%{opacity:.4}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }, { kind: "pipe", type: i1$3.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
18992
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ServiceHealthWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18993
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: ServiceHealthWidgetComponent, isStandalone: true, selector: "mm-service-health-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "@if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n} @else {\n <div\n class=\"service-health\"\n [class.clickable]=\"isClickable\"\n [class.healthy]=\"healthStatus() === 'healthy'\"\n [class.unhealthy]=\"healthStatus() === 'unhealthy'\"\n [class.loading]=\"healthStatus() === 'loading'\"\n (click)=\"onClick()\">\n\n <div class=\"health-indicator\">\n <div class=\"pulse-ring\" [class.pulse-active]=\"showPulse\"></div>\n <div class=\"health-dot\" [class.pulse-dot]=\"showPulse\"></div>\n </div>\n\n <div class=\"health-info\">\n <div class=\"service-name\">{{ serviceName }}</div>\n <div class=\"health-status\">{{ statusLabel }}</div>\n @if (lastChecked()) {\n <div class=\"last-checked\">\n Last checked: {{ lastChecked() | date:'HH:mm:ss' }}\n </div>\n }\n </div>\n\n @if (error()) {\n <div class=\"health-error\">\n {{ error() }}\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%}.service-health{display:flex;align-items:center;gap:16px;padding:16px;height:100%;border-radius:8px;background:#00000008;transition:background .3s ease,box-shadow .3s ease}.service-health.clickable{cursor:pointer}.service-health.clickable:hover{background:#0000000f;box-shadow:0 2px 8px #0000001a}.service-health.healthy .health-dot{background:#10b981}.service-health.healthy .pulse-ring.pulse-active{border-color:#10b981}.service-health.unhealthy .health-dot{background:#ef4444}.service-health.unhealthy .pulse-ring{border-color:#ef4444}.service-health.loading .health-dot{background:#6b7280;animation:pulse-loading 1.5s ease-in-out infinite}.health-indicator{position:relative;width:48px;height:48px;display:flex;align-items:center;justify-content:center}.health-dot{width:16px;height:16px;border-radius:50%;background:#6b7280;z-index:1;transition:background .3s ease}.health-dot.pulse-dot{animation:pulse-dot 2s ease-in-out infinite}.pulse-ring{position:absolute;width:32px;height:32px;border:2px solid transparent;border-radius:50%;opacity:0}.pulse-ring.pulse-active{animation:pulse-ring 2s ease-out infinite}.health-info{flex:1;min-width:0}.service-name{font-size:1rem;font-weight:600;color:var(--kendo-color-on-app-surface, #1f2937);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.health-status{font-size:.875rem;font-weight:500;color:var(--kendo-color-subtle, #6b7280)}.healthy .health-status{color:#10b981}.unhealthy .health-status{color:#ef4444}.last-checked{font-size:.7rem;color:var(--kendo-color-subtle, #9ca3af);margin-top:4px}.health-error{font-size:.75rem;color:var(--kendo-color-error, #dc3545);margin-top:8px}@keyframes pulse-ring{0%{transform:scale(.8);opacity:.8}50%{transform:scale(1.2);opacity:.4}to{transform:scale(1.5);opacity:0}}@keyframes pulse-dot{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.1);opacity:.8}}@keyframes pulse-loading{0%,to{opacity:1}50%{opacity:.4}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }, { kind: "pipe", type: i1$3.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
18480
18994
  }
18481
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ServiceHealthWidgetComponent, decorators: [{
18995
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ServiceHealthWidgetComponent, decorators: [{
18482
18996
  type: Component,
18483
18997
  args: [{ selector: 'mm-service-health-widget', standalone: true, imports: [CommonModule, WidgetNotConfiguredComponent], changeDetection: ChangeDetectionStrategy.Eager, template: "@if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n} @else {\n <div\n class=\"service-health\"\n [class.clickable]=\"isClickable\"\n [class.healthy]=\"healthStatus() === 'healthy'\"\n [class.unhealthy]=\"healthStatus() === 'unhealthy'\"\n [class.loading]=\"healthStatus() === 'loading'\"\n (click)=\"onClick()\">\n\n <div class=\"health-indicator\">\n <div class=\"pulse-ring\" [class.pulse-active]=\"showPulse\"></div>\n <div class=\"health-dot\" [class.pulse-dot]=\"showPulse\"></div>\n </div>\n\n <div class=\"health-info\">\n <div class=\"service-name\">{{ serviceName }}</div>\n <div class=\"health-status\">{{ statusLabel }}</div>\n @if (lastChecked()) {\n <div class=\"last-checked\">\n Last checked: {{ lastChecked() | date:'HH:mm:ss' }}\n </div>\n }\n </div>\n\n @if (error()) {\n <div class=\"health-error\">\n {{ error() }}\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;width:100%;height:100%}.service-health{display:flex;align-items:center;gap:16px;padding:16px;height:100%;border-radius:8px;background:#00000008;transition:background .3s ease,box-shadow .3s ease}.service-health.clickable{cursor:pointer}.service-health.clickable:hover{background:#0000000f;box-shadow:0 2px 8px #0000001a}.service-health.healthy .health-dot{background:#10b981}.service-health.healthy .pulse-ring.pulse-active{border-color:#10b981}.service-health.unhealthy .health-dot{background:#ef4444}.service-health.unhealthy .pulse-ring{border-color:#ef4444}.service-health.loading .health-dot{background:#6b7280;animation:pulse-loading 1.5s ease-in-out infinite}.health-indicator{position:relative;width:48px;height:48px;display:flex;align-items:center;justify-content:center}.health-dot{width:16px;height:16px;border-radius:50%;background:#6b7280;z-index:1;transition:background .3s ease}.health-dot.pulse-dot{animation:pulse-dot 2s ease-in-out infinite}.pulse-ring{position:absolute;width:32px;height:32px;border:2px solid transparent;border-radius:50%;opacity:0}.pulse-ring.pulse-active{animation:pulse-ring 2s ease-out infinite}.health-info{flex:1;min-width:0}.service-name{font-size:1rem;font-weight:600;color:var(--kendo-color-on-app-surface, #1f2937);margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.health-status{font-size:.875rem;font-weight:500;color:var(--kendo-color-subtle, #6b7280)}.healthy .health-status{color:#10b981}.unhealthy .health-status{color:#ef4444}.last-checked{font-size:.7rem;color:var(--kendo-color-subtle, #9ca3af);margin-top:4px}.health-error{font-size:.75rem;color:var(--kendo-color-error, #dc3545);margin-top:8px}@keyframes pulse-ring{0%{transform:scale(.8);opacity:.8}50%{transform:scale(1.2);opacity:.4}to{transform:scale(1.5);opacity:0}}@keyframes pulse-dot{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.1);opacity:.8}}@keyframes pulse-loading{0%,to{opacity:1}50%{opacity:.4}}\n"] }]
18484
18998
  }], propDecorators: { config: [{
@@ -18542,8 +19056,8 @@ class ServiceHealthConfigDialogComponent {
18542
19056
  onCancel() {
18543
19057
  this.windowRef.close();
18544
19058
  }
18545
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ServiceHealthConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18546
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: ServiceHealthConfigDialogComponent, isStandalone: true, selector: "mm-service-health-config-dialog", inputs: { initialServiceType: "initialServiceType", initialCustomEndpoint: "initialCustomEndpoint", initialShowPulse: "initialShowPulse", initialNavigateOnClick: "initialNavigateOnClick", initialDetailRoute: "initialDetailRoute" }, ngImport: i0, template: `
19059
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ServiceHealthConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19060
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: ServiceHealthConfigDialogComponent, isStandalone: true, selector: "mm-service-health-config-dialog", inputs: { initialServiceType: "initialServiceType", initialCustomEndpoint: "initialCustomEndpoint", initialShowPulse: "initialShowPulse", initialNavigateOnClick: "initialNavigateOnClick", initialDetailRoute: "initialDetailRoute" }, ngImport: i0, template: `
18547
19061
  <div class="config-container">
18548
19062
 
18549
19063
  <div class="config-form">
@@ -18621,7 +19135,7 @@ class ServiceHealthConfigDialogComponent {
18621
19135
  </div>
18622
19136
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:20px;padding:16px;flex:1;overflow-y:auto}.form-field{display:flex;flex-direction:column;gap:6px}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.switch-label{font-weight:400!important;margin-left:8px}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.form-section h4{margin:0 0 16px;font-size:.95rem;color:var(--kendo-color-primary, #0d6efd)}.required{color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.SwitchComponent, selector: "kendo-switch", inputs: ["focusableId", "onLabel", "offLabel", "checked", "disabled", "readonly", "tabindex", "size", "thumbRounded", "trackRounded", "tabIndex"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoSwitch"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
18623
19137
  }
18624
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ServiceHealthConfigDialogComponent, decorators: [{
19138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ServiceHealthConfigDialogComponent, decorators: [{
18625
19139
  type: Component,
18626
19140
  args: [{ selector: 'mm-service-health-config-dialog', standalone: true, imports: [
18627
19141
  CommonModule,
@@ -18994,10 +19508,10 @@ class WidgetGroupComponent {
18994
19508
  });
18995
19509
  return resolved.trim();
18996
19510
  }
18997
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
18998
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: WidgetGroupComponent, isStandalone: true, selector: "mm-widget-group", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"widget-group\" [class]=\"layoutClass()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-state\">\n <span class=\"loading-spinner\"></span>\n <span class=\"loading-text\">Loading...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-state\">\n <span class=\"error-icon\">!</span>\n <span class=\"error-message\">{{ error() }}</span>\n </div>\n } @else if (childConfigs().length === 0) {\n <div class=\"empty-state\">\n <span class=\"empty-message\">{{ config.emptyMessage || 'No data available' }}</span>\n </div>\n } @else {\n <div\n class=\"widget-group-grid\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap]=\"gapStyle()\">\n @for (childConfig of childConfigs(); track childConfig.id) {\n <div class=\"widget-group-item\">\n <div class=\"widget-group-item-header\">\n <span class=\"widget-group-item-title\">{{ childConfig.title }}</span>\n </div>\n <div class=\"widget-group-item-content\">\n @switch (config.childTemplate.widgetType) {\n @case ('kpi') {\n <mm-kpi-widget [config]=\"$any(childConfig)\"></mm-kpi-widget>\n }\n @case ('gauge') {\n <mm-gauge-widget [config]=\"$any(childConfig)\"></mm-gauge-widget>\n }\n @case ('entityCard') {\n <mm-entity-card-widget [config]=\"$any(childConfig)\"></mm-entity-card-widget>\n }\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".widget-group{display:flex;flex-direction:column;height:100%;padding:8px;overflow:auto}.widget-group-grid{display:grid;align-content:start;width:100%}.widget-group-item{display:flex;flex-direction:column;background:var(--kendo-color-surface-alt, rgba(0, 0, 0, .03));border:1px solid var(--kendo-color-border, rgba(0, 0, 0, .08));border-radius:4px;overflow:hidden;min-height:100px}.widget-group-item-header{display:flex;align-items:center;padding:6px 10px;background:var(--kendo-color-surface, rgba(0, 0, 0, .02));border-bottom:1px solid var(--kendo-color-border, rgba(0, 0, 0, .08))}.widget-group-item-title{font-size:.75rem;font-weight:600;color:var(--kendo-color-on-surface, #212529);text-transform:uppercase;letter-spacing:.02em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-group-item-content{flex:1;display:flex;align-items:center;justify-content:center;padding:8px;min-height:80px}.loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:var(--kendo-color-subtle, #6c757d)}.loading-spinner{width:24px;height:24px;border:2px solid var(--kendo-color-border, rgba(0, 0, 0, .08));border-top-color:var(--kendo-color-primary, #0d6efd);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.loading-text{font-size:.875rem}.error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:8px;color:var(--kendo-color-error, #dc3545)}.error-icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:#dc35451a;font-weight:700;font-size:1.25rem}.error-message{font-size:.875rem;text-align:center}.empty-state{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-subtle, #6c757d)}.empty-message{font-size:.875rem;font-style:italic}.layout-horizontal .widget-group-grid{grid-auto-flow:column;grid-auto-columns:1fr}.layout-vertical .widget-group-grid{grid-auto-flow:row}.layout-vertical .widget-group-item{min-height:80px}@media(max-width:768px){.widget-group-item-content{min-height:60px;padding:4px}.widget-group-item-header{padding:4px 8px}.widget-group-item-title{font-size:.65rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: KpiWidgetComponent, selector: "mm-kpi-widget", inputs: ["config"] }, { kind: "component", type: GaugeWidgetComponent, selector: "mm-gauge-widget", inputs: ["config"] }, { kind: "component", type: EntityCardWidgetComponent, selector: "mm-entity-card-widget", inputs: ["config"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
19511
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19512
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: WidgetGroupComponent, isStandalone: true, selector: "mm-widget-group", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"widget-group\" [class]=\"layoutClass()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured></mm-widget-not-configured>\n } @else if (isLoading()) {\n <div class=\"loading-state\">\n <span class=\"loading-spinner\"></span>\n <span class=\"loading-text\">Loading...</span>\n </div>\n } @else if (error()) {\n <div class=\"error-state\">\n <span class=\"error-icon\">!</span>\n <span class=\"error-message\">{{ error() }}</span>\n </div>\n } @else if (childConfigs().length === 0) {\n <div class=\"empty-state\">\n <span class=\"empty-message\">{{ config.emptyMessage || 'No data available' }}</span>\n </div>\n } @else {\n <div\n class=\"widget-group-grid\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap]=\"gapStyle()\">\n @for (childConfig of childConfigs(); track childConfig.id) {\n <div class=\"widget-group-item\">\n <div class=\"widget-group-item-header\">\n <span class=\"widget-group-item-title\">{{ childConfig.title }}</span>\n </div>\n <div class=\"widget-group-item-content\">\n @switch (config.childTemplate.widgetType) {\n @case ('kpi') {\n <mm-kpi-widget [config]=\"$any(childConfig)\"></mm-kpi-widget>\n }\n @case ('gauge') {\n <mm-gauge-widget [config]=\"$any(childConfig)\"></mm-gauge-widget>\n }\n @case ('entityCard') {\n <mm-entity-card-widget [config]=\"$any(childConfig)\"></mm-entity-card-widget>\n }\n }\n </div>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".widget-group{display:flex;flex-direction:column;height:100%;padding:8px;overflow:auto}.widget-group-grid{display:grid;align-content:start;width:100%}.widget-group-item{display:flex;flex-direction:column;background:var(--kendo-color-surface-alt, rgba(0, 0, 0, .03));border:1px solid var(--kendo-color-border, rgba(0, 0, 0, .08));border-radius:4px;overflow:hidden;min-height:100px}.widget-group-item-header{display:flex;align-items:center;padding:6px 10px;background:var(--kendo-color-surface, rgba(0, 0, 0, .02));border-bottom:1px solid var(--kendo-color-border, rgba(0, 0, 0, .08))}.widget-group-item-title{font-size:.75rem;font-weight:600;color:var(--kendo-color-on-surface, #212529);text-transform:uppercase;letter-spacing:.02em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget-group-item-content{flex:1;display:flex;align-items:center;justify-content:center;padding:8px;min-height:80px}.loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:var(--kendo-color-subtle, #6c757d)}.loading-spinner{width:24px;height:24px;border:2px solid var(--kendo-color-border, rgba(0, 0, 0, .08));border-top-color:var(--kendo-color-primary, #0d6efd);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.loading-text{font-size:.875rem}.error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:8px;color:var(--kendo-color-error, #dc3545)}.error-icon{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:#dc35451a;font-weight:700;font-size:1.25rem}.error-message{font-size:.875rem;text-align:center}.empty-state{display:flex;align-items:center;justify-content:center;height:100%;color:var(--kendo-color-subtle, #6c757d)}.empty-message{font-size:.875rem;font-style:italic}.layout-horizontal .widget-group-grid{grid-auto-flow:column;grid-auto-columns:1fr}.layout-vertical .widget-group-grid{grid-auto-flow:row}.layout-vertical .widget-group-item{min-height:80px}@media(max-width:768px){.widget-group-item-content{min-height:60px;padding:4px}.widget-group-item-header{padding:4px 8px}.widget-group-item-title{font-size:.65rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: KpiWidgetComponent, selector: "mm-kpi-widget", inputs: ["config"] }, { kind: "component", type: GaugeWidgetComponent, selector: "mm-gauge-widget", inputs: ["config"] }, { kind: "component", type: EntityCardWidgetComponent, selector: "mm-entity-card-widget", inputs: ["config"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
18999
19513
  }
19000
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetGroupComponent, decorators: [{
19514
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetGroupComponent, decorators: [{
19001
19515
  type: Component,
19002
19516
  args: [{ selector: 'mm-widget-group', standalone: true, imports: [
19003
19517
  CommonModule,
@@ -19367,8 +19881,8 @@ class WidgetGroupConfigDialogComponent {
19367
19881
  onCancel() {
19368
19882
  this.windowRef.close();
19369
19883
  }
19370
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetGroupConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19371
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: WidgetGroupConfigDialogComponent, isStandalone: true, selector: "mm-widget-group-config-dialog", inputs: { initialDataSourceMode: "initialDataSourceMode", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialCkTypeId: "initialCkTypeId", initialFilters: "initialFilters", initialMaxItems: "initialMaxItems", initialChildTemplate: "initialChildTemplate", initialLayout: "initialLayout", initialGridColumns: "initialGridColumns", initialMinChildWidth: "initialMinChildWidth", initialGap: "initialGap", initialEmptyMessage: "initialEmptyMessage" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
19884
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetGroupConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19885
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: WidgetGroupConfigDialogComponent, isStandalone: true, selector: "mm-widget-group-config-dialog", inputs: { initialDataSourceMode: "initialDataSourceMode", initialQueryRtId: "initialQueryRtId", initialQueryName: "initialQueryName", initialQueryFamily: "initialQueryFamily", initialCkTypeId: "initialCkTypeId", initialFilters: "initialFilters", initialMaxItems: "initialMaxItems", initialChildTemplate: "initialChildTemplate", initialLayout: "initialLayout", initialGridColumns: "initialGridColumns", initialMinChildWidth: "initialMinChildWidth", initialGap: "initialGap", initialEmptyMessage: "initialEmptyMessage" }, viewQueries: [{ propertyName: "querySelector", first: true, predicate: ["querySelector"], descendants: true }], ngImport: i0, template: `
19372
19886
  <div class="config-container">
19373
19887
 
19374
19888
  <div class="config-form" [class.loading]="isLoadingInitial">
@@ -19690,7 +20204,7 @@ class WidgetGroupConfigDialogComponent {
19690
20204
  </div>
19691
20205
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:20px;padding:16px;position:relative;flex:1;overflow-y:auto}.config-form.loading{pointer-events:none}.form-section{padding:16px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.form-section h4{margin:0 0 16px;font-size:.95rem;color:var(--kendo-color-primary, #0d6efd)}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}.form-field:last-child{margin-bottom:0}.form-field.flex-1{flex:1}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-row{display:flex;gap:16px}.mode-toggle{display:flex;gap:8px}.mode-toggle button{flex:1}.required{color:var(--kendo-color-error, #dc3545)}.query-item{display:flex;flex-direction:column;gap:2px}.query-name{font-weight:500}.query-description{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.column-item{display:flex;justify-content:space-between;gap:16px}.column-path{font-weight:500}.column-type{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: QuerySelectorComponent, selector: "mm-query-selector", inputs: ["placeholder", "hint", "disabled", "acceptFamilies"], outputs: ["querySelected", "queriesLoaded"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
19692
20206
  }
19693
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WidgetGroupConfigDialogComponent, decorators: [{
20207
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: WidgetGroupConfigDialogComponent, decorators: [{
19694
20208
  type: Component,
19695
20209
  args: [{ selector: 'mm-widget-group-config-dialog', standalone: true, imports: [
19696
20210
  CommonModule,
@@ -20107,10 +20621,10 @@ class MarkdownWidgetComponent {
20107
20621
  // Markdown is static content, just re-resolve variables
20108
20622
  this._data.set(this.config?.content ?? '');
20109
20623
  }
20110
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MarkdownWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20111
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: MarkdownWidgetComponent, isStandalone: true, selector: "mm-markdown-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"markdown-widget\"\n [class.loading]=\"isLoading()\"\n [class.error]=\"error()\"\n [ngStyle]=\"containerStyle()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured\n message=\"No markdown content configured.\">\n </mm-widget-not-configured>\n } @else {\n <div class=\"markdown-content mm-prose\">\n <markdown [data]=\"resolvedContent()\"></markdown>\n </div>\n }\n</div>\n", styles: [".markdown-widget{display:flex;flex-direction:column;height:100%;overflow:auto}.markdown-content{flex:1;overflow:auto}:host{--mm-prose-text: #333333;--mm-prose-heading: #1976d2;--mm-prose-link: #1565c0;--mm-prose-link-hover: #0d47a1;--mm-prose-code-bg: #f5f5f5;--mm-prose-code-text: #d32f2f;--mm-prose-pre-bg: #f5f5f5;--mm-prose-pre-border: #e0e0e0;--mm-prose-blockquote-border: #cccccc;--mm-prose-blockquote-bg: rgba(0, 0, 0, .03);--mm-prose-table-header-bg: #f5f5f5;--mm-prose-table-header-text: #333333;--mm-prose-table-border: #e0e0e0;--mm-prose-table-row-even: rgba(0, 0, 0, .02);--mm-prose-strong: #111111;--mm-prose-em: #1565c0;--mm-prose-marker-ul: #1976d2;--mm-prose-marker-ol: #1565c0;--mm-prose-hr-start: #1976d2;--mm-prose-hr-end: #1565c0;--mm-prose-img-border: #e0e0e0;--mm-prose-font: \"Roboto\", sans-serif}:host ::ng-deep .mm-prose{color:var(--mm-prose-text);font-family:var(--mm-prose-font);line-height:1.6}:host ::ng-deep .mm-prose h1,:host ::ng-deep .mm-prose h2,:host ::ng-deep .mm-prose h3,:host ::ng-deep .mm-prose h4,:host ::ng-deep .mm-prose h5,:host ::ng-deep .mm-prose h6{color:var(--mm-prose-heading);font-weight:600;margin-top:1.5em;margin-bottom:.5em;letter-spacing:.5px}:host ::ng-deep .mm-prose h1:first-child,:host ::ng-deep .mm-prose h2:first-child,:host ::ng-deep .mm-prose h3:first-child,:host ::ng-deep .mm-prose h4:first-child,:host ::ng-deep .mm-prose h5:first-child,:host ::ng-deep .mm-prose h6:first-child{margin-top:0}:host ::ng-deep .mm-prose h1{font-size:1.75rem;border-bottom:2px solid var(--mm-prose-heading);padding-bottom:.25em}:host ::ng-deep .mm-prose h2{font-size:1.5rem;border-bottom:1px solid var(--mm-prose-table-border);padding-bottom:.2em}:host ::ng-deep .mm-prose h3{font-size:1.25rem}:host ::ng-deep .mm-prose h4{font-size:1.1rem}:host ::ng-deep .mm-prose h5,:host ::ng-deep .mm-prose h6{font-size:1rem}:host ::ng-deep .mm-prose p{margin-bottom:1em}:host ::ng-deep .mm-prose p:last-child{margin-bottom:0}:host ::ng-deep .mm-prose a{color:var(--mm-prose-link);text-decoration:none;border-bottom:1px solid transparent;transition:all .15s ease}:host ::ng-deep .mm-prose a:hover{color:var(--mm-prose-link-hover);border-bottom-color:var(--mm-prose-link-hover)}:host ::ng-deep .mm-prose ul,:host ::ng-deep .mm-prose ol{margin-bottom:1em;padding-left:1.5em}:host ::ng-deep .mm-prose li{margin-bottom:.25em}:host ::ng-deep .mm-prose ul li::marker{color:var(--mm-prose-marker-ul)}:host ::ng-deep .mm-prose ol li::marker{color:var(--mm-prose-marker-ol)}:host ::ng-deep .mm-prose code{font-family:Roboto Mono,monospace;background:var(--mm-prose-code-bg);color:var(--mm-prose-code-text);padding:.2em .4em;border-radius:4px;font-size:.9em}:host ::ng-deep .mm-prose pre{background:var(--mm-prose-pre-bg);border:1px solid var(--mm-prose-pre-border);border-radius:8px;padding:1em;overflow-x:auto;margin-bottom:1em}:host ::ng-deep .mm-prose pre code{background:transparent;padding:0;color:var(--mm-prose-text)}:host ::ng-deep .mm-prose blockquote{border-left:4px solid var(--mm-prose-blockquote-border);background:var(--mm-prose-blockquote-bg);padding:.75em 1em;margin:1em 0;border-radius:0 8px 8px 0}:host ::ng-deep .mm-prose blockquote p:last-child{margin-bottom:0}:host ::ng-deep .mm-prose table{width:100%;border-collapse:collapse;margin-bottom:1em}:host ::ng-deep .mm-prose th,:host ::ng-deep .mm-prose td{padding:.75em;border:1px solid var(--mm-prose-table-border);text-align:left}:host ::ng-deep .mm-prose th{background:var(--mm-prose-table-header-bg);color:var(--mm-prose-table-header-text);font-weight:600;text-transform:uppercase;font-size:.85em;letter-spacing:.5px}:host ::ng-deep .mm-prose tr:nth-child(2n){background:var(--mm-prose-table-row-even)}:host ::ng-deep .mm-prose hr{border:none;height:2px;background:linear-gradient(90deg,var(--mm-prose-hr-start),var(--mm-prose-hr-end),transparent);margin:1.5em 0}:host ::ng-deep .mm-prose img{max-width:100%;height:auto;border-radius:8px;border:1px solid var(--mm-prose-img-border)}:host ::ng-deep .mm-prose strong,:host ::ng-deep .mm-prose b{font-weight:600;color:var(--mm-prose-strong)}:host ::ng-deep .mm-prose em,:host ::ng-deep .mm-prose i{color:var(--mm-prose-em)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MarkdownModule }, { kind: "component", type: i2$1.MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
20624
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MarkdownWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20625
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: MarkdownWidgetComponent, isStandalone: true, selector: "mm-markdown-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"markdown-widget\"\n [class.loading]=\"isLoading()\"\n [class.error]=\"error()\"\n [ngStyle]=\"containerStyle()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured\n message=\"No markdown content configured.\">\n </mm-widget-not-configured>\n } @else {\n <div class=\"markdown-content mm-prose\">\n <markdown [data]=\"resolvedContent()\"></markdown>\n </div>\n }\n</div>\n", styles: [".markdown-widget{display:flex;flex-direction:column;height:100%;overflow:auto}.markdown-content{flex:1;overflow:auto}:host{--mm-prose-text: #333333;--mm-prose-heading: #1976d2;--mm-prose-link: #1565c0;--mm-prose-link-hover: #0d47a1;--mm-prose-code-bg: #f5f5f5;--mm-prose-code-text: #d32f2f;--mm-prose-pre-bg: #f5f5f5;--mm-prose-pre-border: #e0e0e0;--mm-prose-blockquote-border: #cccccc;--mm-prose-blockquote-bg: rgba(0, 0, 0, .03);--mm-prose-table-header-bg: #f5f5f5;--mm-prose-table-header-text: #333333;--mm-prose-table-border: #e0e0e0;--mm-prose-table-row-even: rgba(0, 0, 0, .02);--mm-prose-strong: #111111;--mm-prose-em: #1565c0;--mm-prose-marker-ul: #1976d2;--mm-prose-marker-ol: #1565c0;--mm-prose-hr-start: #1976d2;--mm-prose-hr-end: #1565c0;--mm-prose-img-border: #e0e0e0;--mm-prose-font: \"Roboto\", sans-serif}:host ::ng-deep .mm-prose{color:var(--mm-prose-text);font-family:var(--mm-prose-font);line-height:1.6}:host ::ng-deep .mm-prose h1,:host ::ng-deep .mm-prose h2,:host ::ng-deep .mm-prose h3,:host ::ng-deep .mm-prose h4,:host ::ng-deep .mm-prose h5,:host ::ng-deep .mm-prose h6{color:var(--mm-prose-heading);font-weight:600;margin-top:1.5em;margin-bottom:.5em;letter-spacing:.5px}:host ::ng-deep .mm-prose h1:first-child,:host ::ng-deep .mm-prose h2:first-child,:host ::ng-deep .mm-prose h3:first-child,:host ::ng-deep .mm-prose h4:first-child,:host ::ng-deep .mm-prose h5:first-child,:host ::ng-deep .mm-prose h6:first-child{margin-top:0}:host ::ng-deep .mm-prose h1{font-size:1.75rem;border-bottom:2px solid var(--mm-prose-heading);padding-bottom:.25em}:host ::ng-deep .mm-prose h2{font-size:1.5rem;border-bottom:1px solid var(--mm-prose-table-border);padding-bottom:.2em}:host ::ng-deep .mm-prose h3{font-size:1.25rem}:host ::ng-deep .mm-prose h4{font-size:1.1rem}:host ::ng-deep .mm-prose h5,:host ::ng-deep .mm-prose h6{font-size:1rem}:host ::ng-deep .mm-prose p{margin-bottom:1em}:host ::ng-deep .mm-prose p:last-child{margin-bottom:0}:host ::ng-deep .mm-prose a{color:var(--mm-prose-link);text-decoration:none;border-bottom:1px solid transparent;transition:all .15s ease}:host ::ng-deep .mm-prose a:hover{color:var(--mm-prose-link-hover);border-bottom-color:var(--mm-prose-link-hover)}:host ::ng-deep .mm-prose ul,:host ::ng-deep .mm-prose ol{margin-bottom:1em;padding-left:1.5em}:host ::ng-deep .mm-prose li{margin-bottom:.25em}:host ::ng-deep .mm-prose ul li::marker{color:var(--mm-prose-marker-ul)}:host ::ng-deep .mm-prose ol li::marker{color:var(--mm-prose-marker-ol)}:host ::ng-deep .mm-prose code{font-family:Roboto Mono,monospace;background:var(--mm-prose-code-bg);color:var(--mm-prose-code-text);padding:.2em .4em;border-radius:4px;font-size:.9em}:host ::ng-deep .mm-prose pre{background:var(--mm-prose-pre-bg);border:1px solid var(--mm-prose-pre-border);border-radius:8px;padding:1em;overflow-x:auto;margin-bottom:1em}:host ::ng-deep .mm-prose pre code{background:transparent;padding:0;color:var(--mm-prose-text)}:host ::ng-deep .mm-prose blockquote{border-left:4px solid var(--mm-prose-blockquote-border);background:var(--mm-prose-blockquote-bg);padding:.75em 1em;margin:1em 0;border-radius:0 8px 8px 0}:host ::ng-deep .mm-prose blockquote p:last-child{margin-bottom:0}:host ::ng-deep .mm-prose table{width:100%;border-collapse:collapse;margin-bottom:1em}:host ::ng-deep .mm-prose th,:host ::ng-deep .mm-prose td{padding:.75em;border:1px solid var(--mm-prose-table-border);text-align:left}:host ::ng-deep .mm-prose th{background:var(--mm-prose-table-header-bg);color:var(--mm-prose-table-header-text);font-weight:600;text-transform:uppercase;font-size:.85em;letter-spacing:.5px}:host ::ng-deep .mm-prose tr:nth-child(2n){background:var(--mm-prose-table-row-even)}:host ::ng-deep .mm-prose hr{border:none;height:2px;background:linear-gradient(90deg,var(--mm-prose-hr-start),var(--mm-prose-hr-end),transparent);margin:1.5em 0}:host ::ng-deep .mm-prose img{max-width:100%;height:auto;border-radius:8px;border:1px solid var(--mm-prose-img-border)}:host ::ng-deep .mm-prose strong,:host ::ng-deep .mm-prose b{font-weight:600;color:var(--mm-prose-strong)}:host ::ng-deep .mm-prose em,:host ::ng-deep .mm-prose i{color:var(--mm-prose-em)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MarkdownModule }, { kind: "component", type: i2$1.MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
20112
20626
  }
20113
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MarkdownWidgetComponent, decorators: [{
20627
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MarkdownWidgetComponent, decorators: [{
20114
20628
  type: Component,
20115
20629
  args: [{ selector: 'mm-markdown-widget', standalone: true, imports: [CommonModule, MarkdownModule, WidgetNotConfiguredComponent], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"markdown-widget\"\n [class.loading]=\"isLoading()\"\n [class.error]=\"error()\"\n [ngStyle]=\"containerStyle()\">\n @if (isNotConfigured()) {\n <mm-widget-not-configured\n message=\"No markdown content configured.\">\n </mm-widget-not-configured>\n } @else {\n <div class=\"markdown-content mm-prose\">\n <markdown [data]=\"resolvedContent()\"></markdown>\n </div>\n }\n</div>\n", styles: [".markdown-widget{display:flex;flex-direction:column;height:100%;overflow:auto}.markdown-content{flex:1;overflow:auto}:host{--mm-prose-text: #333333;--mm-prose-heading: #1976d2;--mm-prose-link: #1565c0;--mm-prose-link-hover: #0d47a1;--mm-prose-code-bg: #f5f5f5;--mm-prose-code-text: #d32f2f;--mm-prose-pre-bg: #f5f5f5;--mm-prose-pre-border: #e0e0e0;--mm-prose-blockquote-border: #cccccc;--mm-prose-blockquote-bg: rgba(0, 0, 0, .03);--mm-prose-table-header-bg: #f5f5f5;--mm-prose-table-header-text: #333333;--mm-prose-table-border: #e0e0e0;--mm-prose-table-row-even: rgba(0, 0, 0, .02);--mm-prose-strong: #111111;--mm-prose-em: #1565c0;--mm-prose-marker-ul: #1976d2;--mm-prose-marker-ol: #1565c0;--mm-prose-hr-start: #1976d2;--mm-prose-hr-end: #1565c0;--mm-prose-img-border: #e0e0e0;--mm-prose-font: \"Roboto\", sans-serif}:host ::ng-deep .mm-prose{color:var(--mm-prose-text);font-family:var(--mm-prose-font);line-height:1.6}:host ::ng-deep .mm-prose h1,:host ::ng-deep .mm-prose h2,:host ::ng-deep .mm-prose h3,:host ::ng-deep .mm-prose h4,:host ::ng-deep .mm-prose h5,:host ::ng-deep .mm-prose h6{color:var(--mm-prose-heading);font-weight:600;margin-top:1.5em;margin-bottom:.5em;letter-spacing:.5px}:host ::ng-deep .mm-prose h1:first-child,:host ::ng-deep .mm-prose h2:first-child,:host ::ng-deep .mm-prose h3:first-child,:host ::ng-deep .mm-prose h4:first-child,:host ::ng-deep .mm-prose h5:first-child,:host ::ng-deep .mm-prose h6:first-child{margin-top:0}:host ::ng-deep .mm-prose h1{font-size:1.75rem;border-bottom:2px solid var(--mm-prose-heading);padding-bottom:.25em}:host ::ng-deep .mm-prose h2{font-size:1.5rem;border-bottom:1px solid var(--mm-prose-table-border);padding-bottom:.2em}:host ::ng-deep .mm-prose h3{font-size:1.25rem}:host ::ng-deep .mm-prose h4{font-size:1.1rem}:host ::ng-deep .mm-prose h5,:host ::ng-deep .mm-prose h6{font-size:1rem}:host ::ng-deep .mm-prose p{margin-bottom:1em}:host ::ng-deep .mm-prose p:last-child{margin-bottom:0}:host ::ng-deep .mm-prose a{color:var(--mm-prose-link);text-decoration:none;border-bottom:1px solid transparent;transition:all .15s ease}:host ::ng-deep .mm-prose a:hover{color:var(--mm-prose-link-hover);border-bottom-color:var(--mm-prose-link-hover)}:host ::ng-deep .mm-prose ul,:host ::ng-deep .mm-prose ol{margin-bottom:1em;padding-left:1.5em}:host ::ng-deep .mm-prose li{margin-bottom:.25em}:host ::ng-deep .mm-prose ul li::marker{color:var(--mm-prose-marker-ul)}:host ::ng-deep .mm-prose ol li::marker{color:var(--mm-prose-marker-ol)}:host ::ng-deep .mm-prose code{font-family:Roboto Mono,monospace;background:var(--mm-prose-code-bg);color:var(--mm-prose-code-text);padding:.2em .4em;border-radius:4px;font-size:.9em}:host ::ng-deep .mm-prose pre{background:var(--mm-prose-pre-bg);border:1px solid var(--mm-prose-pre-border);border-radius:8px;padding:1em;overflow-x:auto;margin-bottom:1em}:host ::ng-deep .mm-prose pre code{background:transparent;padding:0;color:var(--mm-prose-text)}:host ::ng-deep .mm-prose blockquote{border-left:4px solid var(--mm-prose-blockquote-border);background:var(--mm-prose-blockquote-bg);padding:.75em 1em;margin:1em 0;border-radius:0 8px 8px 0}:host ::ng-deep .mm-prose blockquote p:last-child{margin-bottom:0}:host ::ng-deep .mm-prose table{width:100%;border-collapse:collapse;margin-bottom:1em}:host ::ng-deep .mm-prose th,:host ::ng-deep .mm-prose td{padding:.75em;border:1px solid var(--mm-prose-table-border);text-align:left}:host ::ng-deep .mm-prose th{background:var(--mm-prose-table-header-bg);color:var(--mm-prose-table-header-text);font-weight:600;text-transform:uppercase;font-size:.85em;letter-spacing:.5px}:host ::ng-deep .mm-prose tr:nth-child(2n){background:var(--mm-prose-table-row-even)}:host ::ng-deep .mm-prose hr{border:none;height:2px;background:linear-gradient(90deg,var(--mm-prose-hr-start),var(--mm-prose-hr-end),transparent);margin:1.5em 0}:host ::ng-deep .mm-prose img{max-width:100%;height:auto;border-radius:8px;border:1px solid var(--mm-prose-img-border)}:host ::ng-deep .mm-prose strong,:host ::ng-deep .mm-prose b{font-weight:600;color:var(--mm-prose-strong)}:host ::ng-deep .mm-prose em,:host ::ng-deep .mm-prose i{color:var(--mm-prose-em)}\n"] }]
20116
20630
  }], propDecorators: { config: [{
@@ -20147,8 +20661,8 @@ class MarkdownConfigDialogComponent {
20147
20661
  onCancel() {
20148
20662
  this.windowRef.close();
20149
20663
  }
20150
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MarkdownConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20151
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: MarkdownConfigDialogComponent, isStandalone: true, selector: "mm-markdown-config-dialog", inputs: { initialContent: "initialContent", initialResolveVariables: "initialResolveVariables", initialPadding: "initialPadding", initialTextAlign: "initialTextAlign" }, ngImport: i0, template: `
20664
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MarkdownConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20665
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: MarkdownConfigDialogComponent, isStandalone: true, selector: "mm-markdown-config-dialog", inputs: { initialContent: "initialContent", initialResolveVariables: "initialResolveVariables", initialPadding: "initialPadding", initialTextAlign: "initialTextAlign" }, ngImport: i0, template: `
20152
20666
  <div class="config-container">
20153
20667
 
20154
20668
  <div class="config-form">
@@ -20249,7 +20763,7 @@ Variables: $variableName or \${variableName}">
20249
20763
  </div>
20250
20764
  `, isInline: true, styles: [":host{display:block;height:100%;--mm-prose-editor-bg: #f5f5f5;--mm-prose-editor-text: #333333;--mm-prose-editor-placeholder: #999999;--mm-prose-editor-border: #e0e0e0;--mm-prose-preview-border: #e0e0e0;--mm-prose-form-bg: #f5f5f5;--mm-prose-form-border: #e0e0e0;--mm-prose-label-text: #333333;--mm-prose-hint-text: #666666}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{display:flex;flex-direction:column;gap:16px;height:100%;flex:1;overflow-y:auto}.mode-toggle{display:flex;gap:8px}.editor-area{flex:1;min-height:300px;display:flex;flex-direction:column}.markdown-editor{flex:1;width:100%;font-family:Roboto Mono,monospace;font-size:.9rem;padding:12px;border:1px solid var(--mm-prose-editor-border);border-radius:4px;resize:none;background:var(--mm-prose-editor-bg);color:var(--mm-prose-editor-text)}.markdown-editor::placeholder{color:var(--mm-prose-editor-placeholder)}.markdown-preview{flex:1;padding:12px;border:1px solid var(--mm-prose-preview-border);border-radius:4px;overflow:auto;background:var(--mm-prose-editor-bg)}.form-section{padding:12px;background:var(--mm-prose-form-bg);border:1px solid var(--mm-prose-form-border);border-radius:4px}.form-row{display:flex;gap:16px;align-items:flex-start}.form-field{display:flex;flex-direction:column;gap:4px}.form-field label{font-weight:500;display:flex;align-items:center;gap:8px;color:var(--mm-prose-label-text)}.field-hint{margin:0;font-size:.8rem;color:var(--mm-prose-hint-text)}.mm-prose{color:var(--mm-prose-text, #333333);line-height:1.6}.mm-prose h1,.mm-prose h2,.mm-prose h3,.mm-prose h4,.mm-prose h5,.mm-prose h6{color:var(--mm-prose-heading, #1976d2);font-weight:600;margin-top:1em;margin-bottom:.5em}.mm-prose h1{font-size:1.5rem}.mm-prose h2{font-size:1.25rem}.mm-prose h3{font-size:1.1rem}.mm-prose p{margin-bottom:.75em}.mm-prose a{color:var(--mm-prose-link, #1565c0)}.mm-prose code{background:var(--mm-prose-code-bg, #f5f5f5);color:var(--mm-prose-code-text, #d32f2f);padding:.2em .4em;border-radius:4px}.mm-prose pre{background:var(--mm-prose-pre-bg, #f5f5f5);color:var(--mm-prose-text, #333333);padding:1em;border-radius:8px;overflow-x:auto}.mm-prose pre code{background:transparent;color:var(--mm-prose-text, #333333)}.mm-prose blockquote{border-left:4px solid var(--mm-prose-blockquote-border, #6c4da8);background:var(--mm-prose-blockquote-bg, rgba(108, 77, 168, .05));padding:.75em 1em;margin:1em 0;border-radius:0 8px 8px 0}.mm-prose strong,.mm-prose b{color:var(--mm-prose-strong, #111111);font-weight:600}.mm-prose em,.mm-prose i{color:var(--mm-prose-em, #1565c0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: i2.ButtonGroupComponent, selector: "kendo-buttongroup", inputs: ["disabled", "selection", "width", "tabIndex", "navigable"], outputs: ["navigate"], exportAs: ["kendoButtonGroup"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "ngmodule", type: MarkdownModule }, { kind: "component", type: i2$1.MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
20251
20765
  }
20252
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MarkdownConfigDialogComponent, decorators: [{
20766
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MarkdownConfigDialogComponent, decorators: [{
20253
20767
  type: Component,
20254
20768
  args: [{ selector: 'mm-markdown-config-dialog', standalone: true, imports: [
20255
20769
  CommonModule,
@@ -20436,8 +20950,8 @@ class StatusListWidgetComponent {
20436
20950
  const attr = attrs.find(a => a.attributeName === field);
20437
20951
  return attr?.value != null ? String(attr.value) : null;
20438
20952
  }
20439
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatusListWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20440
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: StatusListWidgetComponent, isStandalone: true, selector: "mm-status-list-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
20953
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatusListWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20954
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: StatusListWidgetComponent, isStandalone: true, selector: "mm-status-list-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
20441
20955
  <div class="status-list-widget">
20442
20956
  @if (isNotConfigured()) {
20443
20957
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -20461,7 +20975,7 @@ class StatusListWidgetComponent {
20461
20975
  </div>
20462
20976
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.status-list-widget{height:100%;display:flex;flex-direction:column;padding:8px 0;overflow-y:auto}.status-list{display:flex;flex-direction:column;gap:6px;padding:0 12px}.status-list-item{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-radius:6px;background:var(--mm-status-list-item-bg, rgba(255, 255, 255, .04));border:1px solid var(--mm-status-list-item-border, rgba(255, 255, 255, .06))}.item-label{font-size:.9rem;font-weight:500;color:var(--kendo-color-on-app-surface, inherit)}.item-badge{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;padding:4px 10px;border-radius:4px;color:#fff;white-space:nowrap}.empty-message{text-align:center;padding:16px;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.error-message{text-align:center;padding:16px;color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
20463
20977
  }
20464
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatusListWidgetComponent, decorators: [{
20978
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatusListWidgetComponent, decorators: [{
20465
20979
  type: Component,
20466
20980
  args: [{ selector: 'mm-status-list-widget', standalone: true, imports: [CommonModule, WidgetNotConfiguredComponent], template: `
20467
20981
  <div class="status-list-widget">
@@ -20540,8 +21054,8 @@ class StatusListConfigDialogComponent {
20540
21054
  onCancel() {
20541
21055
  this.windowRef.close();
20542
21056
  }
20543
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatusListConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20544
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: StatusListConfigDialogComponent, isStandalone: true, selector: "mm-status-list-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialLabelField: "initialLabelField", initialStatusField: "initialStatusField", initialStatusColors: "initialStatusColors" }, ngImport: i0, template: `
21057
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatusListConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21058
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: StatusListConfigDialogComponent, isStandalone: true, selector: "mm-status-list-config-dialog", inputs: { initialCkTypeId: "initialCkTypeId", initialLabelField: "initialLabelField", initialStatusField: "initialStatusField", initialStatusColors: "initialStatusColors" }, ngImport: i0, template: `
20545
21059
  <div class="config-container">
20546
21060
  <div class="config-form">
20547
21061
  <div class="form-field">
@@ -20584,7 +21098,7 @@ class StatusListConfigDialogComponent {
20584
21098
  </div>
20585
21099
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.config-form{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.form-field{display:flex;flex-direction:column;gap:6px}.form-field label{font-weight:600;font-size:.9rem}.required{color:var(--kendo-color-error, #dc3545)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.form-section{margin-top:8px}.form-section h4{margin:0 0 4px;font-size:.95rem;font-weight:600}.color-row{display:flex;gap:8px;align-items:center;margin-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
20586
21100
  }
20587
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: StatusListConfigDialogComponent, decorators: [{
21101
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: StatusListConfigDialogComponent, decorators: [{
20588
21102
  type: Component,
20589
21103
  args: [{ selector: 'mm-status-list-config-dialog', standalone: true, imports: [CommonModule, FormsModule, ButtonsModule, InputsModule], template: `
20590
21104
  <div class="config-container">
@@ -20764,8 +21278,8 @@ class SummaryCardWidgetComponent {
20764
21278
  }
20765
21279
  return String(value);
20766
21280
  }
20767
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SummaryCardWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20768
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: SummaryCardWidgetComponent, isStandalone: true, selector: "mm-summary-card-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
21281
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SummaryCardWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21282
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: SummaryCardWidgetComponent, isStandalone: true, selector: "mm-summary-card-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
20769
21283
  <div class="summary-card-widget">
20770
21284
  @if (isNotConfigured()) {
20771
21285
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -20786,7 +21300,7 @@ class SummaryCardWidgetComponent {
20786
21300
  </div>
20787
21301
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.summary-card-widget{height:100%;display:flex;align-items:center;justify-content:center}.summary-grid{display:grid;grid-template-columns:repeat(var(--columns, 2),1fr);gap:8px;padding:8px 12px;width:100%}.tile{text-align:center;padding:12px 8px;border-radius:6px;background:var(--mm-summary-tile-bg, rgba(255, 255, 255, .03))}.tile-value{font-size:1.5rem;font-weight:700;color:inherit}.tile-label{font-size:.7rem;text-transform:uppercase;letter-spacing:.5px;margin-top:4px;opacity:.6}.tile.full-width{grid-column:1 / -1}.tile.primary .tile-value{color:var(--kendo-color-primary, #06b6d4)}.tile.success .tile-value{color:var(--kendo-color-success, #10b981)}.tile.warning .tile-value{color:var(--kendo-color-warning, #f59e0b)}.tile.error .tile-value{color:var(--kendo-color-error, #ef4444)}.error-message{text-align:center;padding:16px;color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
20788
21302
  }
20789
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SummaryCardWidgetComponent, decorators: [{
21303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SummaryCardWidgetComponent, decorators: [{
20790
21304
  type: Component,
20791
21305
  args: [{ selector: 'mm-summary-card-widget', standalone: true, imports: [CommonModule, WidgetNotConfiguredComponent], template: `
20792
21306
  <div class="summary-card-widget">
@@ -20901,8 +21415,8 @@ class SummaryCardConfigDialogComponent {
20901
21415
  onCancel() {
20902
21416
  this.windowRef.close();
20903
21417
  }
20904
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SummaryCardConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20905
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: SummaryCardConfigDialogComponent, isStandalone: true, selector: "mm-summary-card-config-dialog", inputs: { initialColumns: "initialColumns", initialTiles: "initialTiles" }, ngImport: i0, template: `
21418
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SummaryCardConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21419
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: SummaryCardConfigDialogComponent, isStandalone: true, selector: "mm-summary-card-config-dialog", inputs: { initialColumns: "initialColumns", initialTiles: "initialTiles" }, ngImport: i0, template: `
20906
21420
  <div class="config-container">
20907
21421
  <div class="config-form">
20908
21422
  <div class="form-field">
@@ -20963,7 +21477,7 @@ class SummaryCardConfigDialogComponent {
20963
21477
  </div>
20964
21478
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.config-form{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.form-field{display:flex;flex-direction:column;gap:6px}.form-field label{font-weight:600;font-size:.9rem}h4{margin:8px 0 4px;font-size:.95rem}.tile-config{border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;padding:10px;margin-bottom:8px;display:flex;flex-direction:column;gap:6px}.tile-header{display:flex;justify-content:space-between;align-items:center}.tile-row{display:flex;gap:6px;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: PersistentQueryCellEditorComponent, selector: "mm-persistent-query-cell-editor", inputs: ["initialSource", "selectors"], outputs: ["sourceChange"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
20965
21479
  }
20966
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: SummaryCardConfigDialogComponent, decorators: [{
21480
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SummaryCardConfigDialogComponent, decorators: [{
20967
21481
  type: Component,
20968
21482
  args: [{ selector: 'mm-summary-card-config-dialog', standalone: true, imports: [CommonModule, FormsModule, ButtonsModule, InputsModule, DropDownsModule, PersistentQueryCellEditorComponent], template: `
20969
21483
  <div class="config-container">
@@ -21179,8 +21693,8 @@ class AlertBannerWidgetComponent {
21179
21693
  const attr = attrs.find(a => a.attributeName === name);
21180
21694
  return attr?.value != null ? String(attr.value) : null;
21181
21695
  }
21182
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AlertBannerWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21183
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: AlertBannerWidgetComponent, isStandalone: true, selector: "mm-alert-banner-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
21696
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AlertBannerWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21697
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: AlertBannerWidgetComponent, isStandalone: true, selector: "mm-alert-banner-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
21184
21698
  <div class="alert-banner-widget">
21185
21699
  @if (isNotConfigured()) {
21186
21700
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -21206,7 +21720,7 @@ class AlertBannerWidgetComponent {
21206
21720
  </div>
21207
21721
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.alert-banner-widget{height:100%;display:flex;align-items:center}.alert-banner{display:flex;align-items:center;gap:10px;width:100%;padding:10px 16px;border-left:4px solid var(--alert-color, #6b7280);background:color-mix(in srgb,var(--alert-color, #6b7280) 10%,transparent)}.alert-banner.critical{animation:pulse-bg 1.5s ease-in-out infinite}@keyframes pulse-bg{0%,to{background:color-mix(in srgb,var(--alert-color) 10%,transparent)}50%{background:color-mix(in srgb,var(--alert-color) 25%,transparent)}}.alert-icon{flex-shrink:0;color:var(--alert-color, #6b7280)}.alert-severity-badge{font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 8px;border-radius:3px;background:var(--alert-color, #6b7280);color:#fff;white-space:nowrap;flex-shrink:0}.alert-message{flex:1;font-size:.85rem;color:var(--kendo-color-on-app-surface, inherit);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.alert-counter{font-size:.7rem;opacity:.5;white-space:nowrap;flex-shrink:0}.no-alerts{border-left-color:var(--mm-alert-debug, #6b7280);opacity:.5}.error-message{text-align:center;padding:16px;width:100%;color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
21208
21722
  }
21209
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AlertBannerWidgetComponent, decorators: [{
21723
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AlertBannerWidgetComponent, decorators: [{
21210
21724
  type: Component,
21211
21725
  args: [{ selector: 'mm-alert-banner-widget', standalone: true, imports: [CommonModule, SVGIconModule, WidgetNotConfiguredComponent], template: `
21212
21726
  <div class="alert-banner-widget">
@@ -21255,8 +21769,8 @@ class AlertBannerConfigDialogComponent {
21255
21769
  onCancel() {
21256
21770
  this.windowRef.close();
21257
21771
  }
21258
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AlertBannerConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21259
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", type: AlertBannerConfigDialogComponent, isStandalone: true, selector: "mm-alert-banner-config-dialog", ngImport: i0, template: `
21772
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AlertBannerConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21773
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: AlertBannerConfigDialogComponent, isStandalone: true, selector: "mm-alert-banner-config-dialog", ngImport: i0, template: `
21260
21774
  <div class="config-form">
21261
21775
  <div class="form-group">
21262
21776
  <kendo-label text="CK Type ID">
@@ -21280,7 +21794,7 @@ class AlertBannerConfigDialogComponent {
21280
21794
  </div>
21281
21795
  `, isInline: true, styles: [".config-form{display:flex;flex-direction:column;gap:12px;padding:16px}.form-group{display:flex;flex-direction:column;gap:4px}.mm-dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: LabelModule }, { kind: "component", type: i4$1.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
21282
21796
  }
21283
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AlertBannerConfigDialogComponent, decorators: [{
21797
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AlertBannerConfigDialogComponent, decorators: [{
21284
21798
  type: Component,
21285
21799
  args: [{ selector: 'mm-alert-banner-config-dialog', standalone: true, imports: [CommonModule, FormsModule, ButtonsModule, InputsModule, LabelModule], template: `
21286
21800
  <div class="config-form">
@@ -21395,8 +21909,8 @@ class AlertListWidgetComponent {
21395
21909
  const attr = attrs.find(a => a.attributeName === name);
21396
21910
  return attr?.value != null ? String(attr.value) : null;
21397
21911
  }
21398
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AlertListWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21399
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: AlertListWidgetComponent, isStandalone: true, selector: "mm-alert-list-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
21912
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AlertListWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21913
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: AlertListWidgetComponent, isStandalone: true, selector: "mm-alert-list-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
21400
21914
  <div class="alert-list-widget">
21401
21915
  @if (isNotConfigured()) {
21402
21916
  <mm-widget-not-configured></mm-widget-not-configured>
@@ -21424,7 +21938,7 @@ class AlertListWidgetComponent {
21424
21938
  </div>
21425
21939
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.alert-list-widget{height:100%;display:flex;flex-direction:column;overflow-y:auto;padding:8px 0}.alert-list{display:flex;flex-direction:column;gap:4px;padding:0 12px}.alert-item{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:6px;border-left:3px solid var(--alert-color, #6b7280);background:var(--mm-alert-list-item-bg, rgba(255, 255, 255, .03))}.alert-icon{flex-shrink:0;color:var(--alert-color, #6b7280)}.alert-badge{font-size:.6rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:2px 6px;border-radius:3px;color:#fff;white-space:nowrap;flex-shrink:0}.alert-message{flex:1;font-size:.8rem;color:var(--kendo-color-on-app-surface, inherit);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.alert-time{font-size:.7rem;opacity:.5;white-space:nowrap;flex-shrink:0}.empty-message{text-align:center;padding:16px;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.error-message{text-align:center;padding:16px;color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: WidgetNotConfiguredComponent, selector: "mm-widget-not-configured" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
21426
21940
  }
21427
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AlertListWidgetComponent, decorators: [{
21941
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AlertListWidgetComponent, decorators: [{
21428
21942
  type: Component,
21429
21943
  args: [{ selector: 'mm-alert-list-widget', standalone: true, imports: [CommonModule, SVGIconModule, WidgetNotConfiguredComponent], template: `
21430
21944
  <div class="alert-list-widget">
@@ -21475,8 +21989,8 @@ class AlertListConfigDialogComponent {
21475
21989
  onCancel() {
21476
21990
  this.windowRef.close();
21477
21991
  }
21478
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AlertListConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21479
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", type: AlertListConfigDialogComponent, isStandalone: true, selector: "mm-alert-list-config-dialog", ngImport: i0, template: `
21992
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AlertListConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21993
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: AlertListConfigDialogComponent, isStandalone: true, selector: "mm-alert-list-config-dialog", ngImport: i0, template: `
21480
21994
  <div class="config-form">
21481
21995
  <div class="form-group">
21482
21996
  <kendo-label text="CK Type ID">
@@ -21495,7 +22009,7 @@ class AlertListConfigDialogComponent {
21495
22009
  </div>
21496
22010
  `, isInline: true, styles: [".config-form{display:flex;flex-direction:column;gap:12px;padding:16px}.form-group{display:flex;flex-direction:column;gap:4px}.mm-dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: LabelModule }, { kind: "component", type: i4$1.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
21497
22011
  }
21498
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AlertListConfigDialogComponent, decorators: [{
22012
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AlertListConfigDialogComponent, decorators: [{
21499
22013
  type: Component,
21500
22014
  args: [{ selector: 'mm-alert-list-config-dialog', standalone: true, imports: [CommonModule, FormsModule, ButtonsModule, InputsModule, LabelModule], template: `
21501
22015
  <div class="config-form">
@@ -21649,10 +22163,10 @@ Return at most ${context.maxInsights ?? 4} insights. No markdown, no explanation
21649
22163
  severity: 'info'
21650
22164
  }];
21651
22165
  }
21652
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AiInsightsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
21653
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AiInsightsService, providedIn: 'root' });
22166
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AiInsightsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
22167
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AiInsightsService, providedIn: 'root' });
21654
22168
  }
21655
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AiInsightsService, decorators: [{
22169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AiInsightsService, decorators: [{
21656
22170
  type: Injectable,
21657
22171
  args: [{ providedIn: 'root' }]
21658
22172
  }] });
@@ -21741,8 +22255,8 @@ class AiInsightsWidgetComponent {
21741
22255
  this.refreshTimer = null;
21742
22256
  }
21743
22257
  }
21744
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AiInsightsWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21745
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: AiInsightsWidgetComponent, isStandalone: true, selector: "mm-ai-insights-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
22258
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AiInsightsWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22259
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: AiInsightsWidgetComponent, isStandalone: true, selector: "mm-ai-insights-widget", inputs: { config: "config" }, usesOnChanges: true, ngImport: i0, template: `
21746
22260
  <div class="ai-insights-widget">
21747
22261
  @if (isLoading() && !insights()) {
21748
22262
  <div class="loading-state">
@@ -21774,7 +22288,7 @@ class AiInsightsWidgetComponent {
21774
22288
  </div>
21775
22289
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.ai-insights-widget{height:100%;overflow-y:auto;padding:8px 12px}.loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;opacity:.6}.loading-dots{display:flex;gap:6px}.loading-dots span{width:8px;height:8px;border-radius:50%;background:var(--kendo-color-primary, #06b6d4);animation:pulse-dot 1.4s ease-in-out infinite}.loading-dots span:nth-child(2){animation-delay:.2s}.loading-dots span:nth-child(3){animation-delay:.4s}@keyframes pulse-dot{0%,80%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1.2)}}.loading-text{font-size:.8rem}.insights-list{display:flex;flex-direction:column;gap:8px}.insight-card{display:flex;gap:10px;padding:10px 12px;border-radius:6px;border-left:3px solid var(--mm-ai-border-color, #6b7280);background:var(--mm-ai-card-bg, rgba(255, 255, 255, .03))}.insight-icon{flex-shrink:0;padding-top:2px;color:var(--mm-ai-border-color, #6b7280)}.insight-content{flex:1;min-width:0}.insight-title{font-size:.85rem;font-weight:600;margin-bottom:4px;color:var(--kendo-color-on-app-surface, inherit)}.insight-description{font-size:.8rem;line-height:1.4;opacity:.8}.severity-info{--mm-ai-border-color: var(--mm-ai-info, #3b82f6)}.severity-warning{--mm-ai-border-color: var(--mm-ai-warning, #f59e0b)}.severity-success{--mm-ai-border-color: var(--mm-ai-success, #10b981)}.severity-critical{--mm-ai-border-color: var(--mm-ai-critical, #ef4444)}.refresh-indicator{text-align:center;padding:8px;font-size:.7rem;opacity:.5}.error-state{text-align:center;padding:16px;color:var(--kendo-color-error, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
21776
22290
  }
21777
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AiInsightsWidgetComponent, decorators: [{
22291
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AiInsightsWidgetComponent, decorators: [{
21778
22292
  type: Component,
21779
22293
  args: [{ selector: 'mm-ai-insights-widget', standalone: true, imports: [CommonModule, SVGIconModule, WidgetNotConfiguredComponent], template: `
21780
22294
  <div class="ai-insights-widget">
@@ -21832,8 +22346,8 @@ class AiInsightsConfigDialogComponent {
21832
22346
  onCancel() {
21833
22347
  this.windowRef.close();
21834
22348
  }
21835
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AiInsightsConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21836
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", type: AiInsightsConfigDialogComponent, isStandalone: true, selector: "mm-ai-insights-config-dialog", ngImport: i0, template: `
22349
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AiInsightsConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22350
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: AiInsightsConfigDialogComponent, isStandalone: true, selector: "mm-ai-insights-config-dialog", ngImport: i0, template: `
21837
22351
  <div class="config-form">
21838
22352
  <div class="form-group">
21839
22353
  <kendo-label text="Anthropic API Key (optional for demo)">
@@ -21870,7 +22384,7 @@ class AiInsightsConfigDialogComponent {
21870
22384
  </div>
21871
22385
  `, isInline: true, styles: [".config-form{display:flex;flex-direction:column;gap:12px;padding:16px}.form-group{display:flex;flex-direction:column;gap:4px}.form-row{display:flex;gap:16px}.form-row .form-group{flex:1}.mm-dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}.hint{font-size:.75rem;opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: LabelModule }, { kind: "component", type: i4$1.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
21872
22386
  }
21873
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AiInsightsConfigDialogComponent, decorators: [{
22387
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AiInsightsConfigDialogComponent, decorators: [{
21874
22388
  type: Component,
21875
22389
  args: [{ selector: 'mm-ai-insights-config-dialog', standalone: true, imports: [CommonModule, FormsModule, ButtonsModule, InputsModule, LabelModule], template: `
21876
22390
  <div class="config-form">
@@ -22495,10 +23009,10 @@ class ProcessDataService {
22495
23009
  const variables = this.stateService.getVariables();
22496
23010
  return this.variableService.convertToFieldFilterDto(filters, variables);
22497
23011
  }
22498
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ProcessDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
22499
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ProcessDataService });
23012
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ProcessDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
23013
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ProcessDataService });
22500
23014
  }
22501
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ProcessDataService, decorators: [{
23015
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ProcessDataService, decorators: [{
22502
23016
  type: Injectable
22503
23017
  }] });
22504
23018
 
@@ -24097,8 +24611,8 @@ class ProcessWidgetComponent {
24097
24611
  }
24098
24612
  return primitive;
24099
24613
  }
24100
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ProcessWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
24101
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: ProcessWidgetComponent, isStandalone: true, selector: "mm-process-widget", inputs: { config: "config" }, providers: [ProcessDataService, ExpressionEvaluatorService], viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["containerRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
24614
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ProcessWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
24615
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: ProcessWidgetComponent, isStandalone: true, selector: "mm-process-widget", inputs: { config: "config" }, providers: [ProcessDataService, ExpressionEvaluatorService], viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["containerRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
24102
24616
  <div class="process-widget"
24103
24617
  [class.loading]="isLoading()"
24104
24618
  [class.error]="error()"
@@ -25097,7 +25611,7 @@ class ProcessWidgetComponent {
25097
25611
  </div>
25098
25612
  `, isInline: true, styles: [":host{display:block;width:100%;height:100%}.process-widget{display:flex;align-items:center;justify-content:center;width:100%;height:100%;overflow:hidden;background-color:var(--process-bg, #fafafa)}.loading-overlay{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;color:var(--kendo-color-subtle, #666)}.loading-spinner{width:40px;height:40px;border:3px solid #e0e0e0;border-top-color:var(--kendo-color-primary, #1976d2);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.error-container{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:1rem;color:var(--kendo-color-error, #d32f2f)}.error-icon{font-size:2rem}.error-message{font-size:.875rem;text-align:center}.no-config{display:flex;align-items:center;justify-content:center;color:var(--kendo-color-subtle, #999);font-style:italic}.diagram-container{position:relative;overflow:hidden}.diagram-container.fit-to-bounds{width:100%!important;height:100%!important}.process-svg{display:block}.diagram-container.fit-to-bounds .process-svg{width:100%;height:100%}.canvas-background{fill:var(--process-canvas-bg, #fafafa)}.element{cursor:default}.element.interactive{cursor:pointer}.element.interactive:hover{filter:brightness(1.1)}.tank-fill{transition:height .5s ease-out,y .5s ease-out}.tank-label{pointer-events:none;-webkit-user-select:none;user-select:none}.pump-element .rotating{animation:rotate 1s linear infinite;transform-origin:center}@keyframes rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.blinking{animation:blink 1s ease-in-out infinite}@keyframes blink{0%,to{opacity:1}50%{opacity:.3}}.connection-flow{animation:flow 2s linear infinite}@keyframes flow{0%{stroke-dashoffset:0}to{stroke-dashoffset:-40}}.digital-display-value{font-family:Courier New,monospace;letter-spacing:2px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.Eager });
25099
25613
  }
25100
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ProcessWidgetComponent, decorators: [{
25614
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ProcessWidgetComponent, decorators: [{
25101
25615
  type: Component,
25102
25616
  args: [{ selector: 'mm-process-widget', standalone: true, imports: [CommonModule], providers: [ProcessDataService, ExpressionEvaluatorService], template: `
25103
25617
  <div class="process-widget"
@@ -26676,8 +27190,8 @@ class ProcessConfigDialogComponent {
26676
27190
  onCancel() {
26677
27191
  this.windowRef.close();
26678
27192
  }
26679
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ProcessConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
26680
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: ProcessConfigDialogComponent, isStandalone: true, selector: "mm-process-config-dialog", inputs: { initialProcessDiagramRtId: "initialProcessDiagramRtId", initialFitToBounds: "initialFitToBounds", initialAllowZoom: "initialAllowZoom", initialAllowPan: "initialAllowPan", initialShowToolbar: "initialShowToolbar", initialInitialZoom: "initialInitialZoom", initialDataBindingMode: "initialDataBindingMode", initialBindingCkTypeId: "initialBindingCkTypeId", initialBindingRtId: "initialBindingRtId", initialBindingQueryRtId: "initialBindingQueryRtId", initialBindingQueryName: "initialBindingQueryName", initialBindingQueryFamily: "initialBindingQueryFamily", initialBindingIgnoreTimeFilter: "initialBindingIgnoreTimeFilter", initialBindingEntitySelectorId: "initialBindingEntitySelectorId", initialBindingFilters: "initialBindingFilters", initialPropertyMappings: "initialPropertyMappings" }, providers: [ProcessDataService], ngImport: i0, template: `
27193
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ProcessConfigDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
27194
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: ProcessConfigDialogComponent, isStandalone: true, selector: "mm-process-config-dialog", inputs: { initialProcessDiagramRtId: "initialProcessDiagramRtId", initialFitToBounds: "initialFitToBounds", initialAllowZoom: "initialAllowZoom", initialAllowPan: "initialAllowPan", initialShowToolbar: "initialShowToolbar", initialInitialZoom: "initialInitialZoom", initialDataBindingMode: "initialDataBindingMode", initialBindingCkTypeId: "initialBindingCkTypeId", initialBindingRtId: "initialBindingRtId", initialBindingQueryRtId: "initialBindingQueryRtId", initialBindingQueryName: "initialBindingQueryName", initialBindingQueryFamily: "initialBindingQueryFamily", initialBindingIgnoreTimeFilter: "initialBindingIgnoreTimeFilter", initialBindingEntitySelectorId: "initialBindingEntitySelectorId", initialBindingFilters: "initialBindingFilters", initialPropertyMappings: "initialPropertyMappings" }, providers: [ProcessDataService], ngImport: i0, template: `
26681
27195
  <div class="config-container">
26682
27196
 
26683
27197
  <div class="config-form">
@@ -27010,7 +27524,7 @@ class ProcessConfigDialogComponent {
27010
27524
  </div>
27011
27525
  `, isInline: true, styles: [":host{display:block;height:100%}.config-container{display:flex;flex-direction:column;height:100%}.action-bar{display:flex;justify-content:flex-end;gap:8px;padding:8px 16px;border-top:1px solid var(--kendo-color-border, #dee2e6)}.config-form{flex:1;overflow-y:auto;padding:16px}.tab-content{padding:16px;min-height:200px;position:relative}.tab-content.loading{pointer-events:none}.section-hint{margin:0 0 16px;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.empty-hint{text-align:center;padding:24px;color:var(--kendo-color-subtle, #6c757d);font-style:italic}.form-field{display:flex;flex-direction:column;gap:6px;margin-bottom:16px}.form-field:last-child{margin-bottom:0}.form-field.disabled{opacity:.6}.form-field label{font-weight:600;font-size:.9rem;color:var(--kendo-color-on-app-surface, #212529)}.required{color:var(--kendo-color-error, #dc3545)}.field-hint{margin:0;font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.field-hint.warning{color:var(--kendo-color-warning, #ffc107)}.form-row{display:flex;gap:24px;margin-bottom:12px}.form-row:last-child{margin-bottom:0}.mode-toggle{display:flex;gap:8px}.checkbox-field{flex-direction:row;align-items:flex-start}.checkbox-field label{display:flex;align-items:center;gap:8px;cursor:pointer;font-weight:400}.checkbox-field .field-hint{margin-top:4px;margin-left:28px}.preview-section{margin-top:16px;padding:12px;background:var(--kendo-color-surface-alt, #f8f9fa);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.preview-info{display:flex;flex-direction:column;gap:6px}.preview-item{display:flex;justify-content:space-between;padding:6px 10px;background:var(--kendo-color-surface, #ffffff);border-radius:4px}.preview-label{font-weight:500;font-size:.85rem;color:var(--kendo-color-subtle, #6c757d)}.preview-value{font-weight:600;font-size:.85rem;color:var(--kendo-color-on-app-surface, #212529)}.diagram-item{display:flex;justify-content:space-between;gap:16px}.diagram-name{font-weight:500}.diagram-size{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.query-item{display:flex;flex-direction:column;gap:2px}.query-name{font-weight:500}.query-description{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.property-mappings-table{display:flex;flex-direction:column;gap:6px}.mapping-header{display:grid;grid-template-columns:minmax(80px,1fr) 55px 85px minmax(80px,1fr) minmax(90px,1.2fr);gap:6px;padding:6px 10px;background:var(--kendo-color-surface-alt, #f8f9fa);border-radius:4px;font-weight:600;font-size:.7rem;color:var(--kendo-color-subtle, #6c757d);text-transform:uppercase}.mapping-row{display:grid;grid-template-columns:minmax(80px,1fr) 55px 85px minmax(80px,1fr) minmax(90px,1.2fr);gap:6px;padding:6px 10px;background:var(--kendo-color-surface, #ffffff);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px;align-items:center}.col-property{font-weight:500;font-size:.85rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.col-type.type-badge{font-size:.65rem;padding:2px 4px;background:var(--kendo-color-surface-alt, #f8f9fa);border-radius:10px;text-align:center;text-transform:uppercase;color:var(--kendo-color-subtle, #6c757d)}.col-expression kendo-textbox{font-family:Consolas,Monaco,monospace;font-size:.8rem}.expression-help{margin-top:12px}.expression-help code{background:var(--kendo-color-surface-alt, #f8f9fa);padding:1px 4px;border-radius:3px;font-size:.75rem}.loading-hint{font-style:italic;color:var(--kendo-color-subtle, #6c757d);padding:8px;text-align:center}:host ::ng-deep kendo-tabstrip{border:none}:host ::ng-deep .k-tabstrip-items-wrapper{border-bottom:1px solid var(--kendo-color-border, #dee2e6)}:host ::ng-deep .k-tabstrip-content{border:none;padding:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "component", type: i4.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: LayoutModule }, { kind: "component", type: i5.TabStripComponent, selector: "kendo-tabstrip", inputs: ["height", "animate", "tabAlignment", "tabPosition", "keepTabContent", "closable", "scrollable", "size", "closeIcon", "closeIconClass", "closeSVGIcon", "showContentArea"], outputs: ["tabSelect", "tabClose", "tabScroll"], exportAs: ["kendoTabStrip"] }, { kind: "component", type: i5.TabStripTabComponent, selector: "kendo-tabstrip-tab", inputs: ["title", "disabled", "cssClass", "cssStyle", "selected", "closable", "closeIcon", "closeIconClass", "closeSVGIcon"], exportAs: ["kendoTabStripTab"] }, { kind: "directive", type: i5.TabContentDirective, selector: "[kendoTabContent]" }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }, { kind: "component", type: FieldFilterEditorComponent, selector: "mm-field-filter-editor", inputs: ["availableAttributes", "ckTypeId", "hideNavigationProperties", "attributePaths", "enableVariables", "availableVariables", "filters"], outputs: ["filtersChange"] }, { kind: "component", type: LoadingOverlayComponent, selector: "mm-loading-overlay", inputs: ["loading"] }, { kind: "component", type: SdTimeFilterToggleComponent, selector: "mm-sd-time-filter-toggle", inputs: ["family", "ignoreTimeFilter"], outputs: ["ignoreTimeFilterChange"] }, { kind: "component", type: EntitySelectorScopePickerComponent, selector: "mm-entity-selector-scope-picker", inputs: ["family", "entitySelectorId", "selectors"], outputs: ["entitySelectorIdChange"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
27012
27526
  }
27013
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: ProcessConfigDialogComponent, decorators: [{
27527
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ProcessConfigDialogComponent, decorators: [{
27014
27528
  type: Component,
27015
27529
  args: [{ selector: 'mm-process-config-dialog', standalone: true, imports: [
27016
27530
  CommonModule,
@@ -27634,6 +28148,15 @@ function buildDataSourceFromPersisted(data, config) {
27634
28148
  if (typeof config['entitySelectorId'] === 'string' && config['entitySelectorId']) {
27635
28149
  persisted.entitySelectorId = config['entitySelectorId'];
27636
28150
  }
28151
+ // Resolution-aware routing (AB#4290).
28152
+ if (config['resolutionAware'] === true) {
28153
+ persisted.resolutionAware = true;
28154
+ }
28155
+ const persistedAggregation = config['requiredAggregation'];
28156
+ if (persistedAggregation === 'AVG' || persistedAggregation === 'MIN' || persistedAggregation === 'MAX'
28157
+ || persistedAggregation === 'SUM' || persistedAggregation === 'COUNT') {
28158
+ persisted.requiredAggregation = persistedAggregation;
28159
+ }
27637
28160
  return persisted;
27638
28161
  }
27639
28162
  if (data.dataSourceType === 'static') {
@@ -27885,6 +28408,7 @@ function registerDefaultWidgets(registry) {
27885
28408
  queryValueField: widget.queryValueField,
27886
28409
  queryCategoryField: widget.queryCategoryField,
27887
28410
  queryCategoryValue: widget.queryCategoryValue,
28411
+ valueMultiplier: widget.valueMultiplier,
27888
28412
  filters: widget.filters,
27889
28413
  ...(isPersistentQuery && {
27890
28414
  queryName: widget.dataSource.queryName,
@@ -27932,6 +28456,7 @@ function registerDefaultWidgets(registry) {
27932
28456
  queryValueField: config['queryValueField'],
27933
28457
  queryCategoryField: config['queryCategoryField'],
27934
28458
  queryCategoryValue: config['queryCategoryValue'],
28459
+ valueMultiplier: config['valueMultiplier'],
27935
28460
  prefix: config['prefix'],
27936
28461
  suffix: config['suffix'],
27937
28462
  icon: config['icon'],
@@ -28693,6 +29218,8 @@ function registerDefaultWidgets(registry) {
28693
29218
  initialQueryFamily: isPersistentQuery ? dataSource.queryFamily : undefined,
28694
29219
  initialIgnoreTimeFilter: isPersistentQuery ? dataSource.ignoreTimeFilter : undefined,
28695
29220
  initialEntitySelectorId: isPersistentQuery ? dataSource.entitySelectorId : undefined,
29221
+ initialResolutionAware: isPersistentQuery ? dataSource.resolutionAware : undefined,
29222
+ initialRequiredAggregation: isPersistentQuery ? dataSource.requiredAggregation : undefined,
28696
29223
  initialChartType: lineWidget.chartType,
28697
29224
  initialCategoryField: lineWidget.categoryField,
28698
29225
  initialSeriesGroupField: lineWidget.seriesGroupField,
@@ -28701,6 +29228,7 @@ function registerDefaultWidgets(registry) {
28701
29228
  initialShowLegend: lineWidget.showLegend,
28702
29229
  initialLegendPosition: lineWidget.legendPosition,
28703
29230
  initialShowMarkers: lineWidget.showMarkers,
29231
+ initialShowDataBadge: lineWidget.showDataBadge,
28704
29232
  initialReferenceLines: lineWidget.referenceLines,
28705
29233
  initialFilters: lineWidget.filters
28706
29234
  };
@@ -28712,7 +29240,9 @@ function registerDefaultWidgets(registry) {
28712
29240
  queryName: result.queryName,
28713
29241
  queryFamily: result.queryFamily,
28714
29242
  ignoreTimeFilter: result.ignoreTimeFilter,
28715
- entitySelectorId: result.entitySelectorId
29243
+ entitySelectorId: result.entitySelectorId,
29244
+ resolutionAware: result.resolutionAware,
29245
+ requiredAggregation: result.requiredAggregation
28716
29246
  };
28717
29247
  const filters = result.filters?.map(f => ({
28718
29248
  attributePath: f.attributePath,
@@ -28730,6 +29260,7 @@ function registerDefaultWidgets(registry) {
28730
29260
  showLegend: result.showLegend,
28731
29261
  legendPosition: result.legendPosition,
28732
29262
  showMarkers: result.showMarkers,
29263
+ showDataBadge: result.showDataBadge,
28733
29264
  referenceLines: result.referenceLines,
28734
29265
  filters
28735
29266
  };
@@ -28760,6 +29291,7 @@ function registerDefaultWidgets(registry) {
28760
29291
  showLegend: widget.showLegend,
28761
29292
  legendPosition: widget.legendPosition,
28762
29293
  showMarkers: widget.showMarkers,
29294
+ showDataBadge: widget.showDataBadge,
28763
29295
  referenceLines: widget.referenceLines,
28764
29296
  queryName: widget.dataSource.queryName,
28765
29297
  queryRtId: widget.dataSource.queryRtId,
@@ -28772,6 +29304,12 @@ function registerDefaultWidgets(registry) {
28772
29304
  ...(widget.dataSource.entitySelectorId && {
28773
29305
  entitySelectorId: widget.dataSource.entitySelectorId
28774
29306
  }),
29307
+ ...(widget.dataSource.resolutionAware && {
29308
+ resolutionAware: true
29309
+ }),
29310
+ ...(widget.dataSource.requiredAggregation && {
29311
+ requiredAggregation: widget.dataSource.requiredAggregation
29312
+ }),
28775
29313
  filters: widget.filters
28776
29314
  }
28777
29315
  }),
@@ -28791,6 +29329,7 @@ function registerDefaultWidgets(registry) {
28791
29329
  showLegend: config['showLegend'] ?? true,
28792
29330
  legendPosition: config['legendPosition'] ?? 'right',
28793
29331
  showMarkers: config['showMarkers'] ?? false,
29332
+ showDataBadge: config['showDataBadge'] ?? true,
28794
29333
  referenceLines: config['referenceLines'],
28795
29334
  filters: config['filters']
28796
29335
  };
@@ -30073,10 +30612,10 @@ class EntitySelectorEditorComponent {
30073
30612
  emitChange() {
30074
30613
  this.entitySelectorsChange.emit([...this.entitySelectors]);
30075
30614
  }
30076
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntitySelectorEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30077
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: EntitySelectorEditorComponent, isStandalone: true, selector: "mm-entity-selector-editor", inputs: { entitySelectors: "entitySelectors", existingVariableNames: "existingVariableNames" }, outputs: { entitySelectorsChange: "entitySelectorsChange", editingStateChange: "editingStateChange" }, ngImport: i0, template: "<div class=\"entity-selector-editor\">\n @if (!isEditing) {\n <!-- Selector List -->\n <div class=\"selector-list\">\n @for (selector of entitySelectors; track selector.id; let i = $index) {\n <div class=\"selector-item\">\n <div class=\"selector-info\">\n <span class=\"selector-label\">{{ selector.label }}</span>\n <span class=\"selector-mode\">{{ getModeLabel(selector) }}</span>\n <span class=\"selector-ck-type\">{{ selector.ckTypeId }}</span>\n <span class=\"selector-mappings\">{{ getMappingSummary(selector) }}</span>\n </div>\n <div class=\"selector-actions\">\n <button\n kendoButton\n [svgIcon]=\"pencilIcon\"\n (click)=\"editSelector(i)\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Edit selector\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"trashIcon\"\n (click)=\"removeSelector(i)\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Remove selector\"\n class=\"remove-btn\">\n </button>\n </div>\n </div>\n }\n\n @if (entitySelectors.length === 0) {\n <div class=\"empty-state\">\n No entity selectors configured. Add one to enable entity-based variables.\n </div>\n }\n </div>\n\n <div class=\"add-button-row\">\n <button\n kendoButton\n [svgIcon]=\"plusIcon\"\n (click)=\"addSelector()\"\n themeColor=\"primary\">\n Add Entity Selector\n </button>\n </div>\n } @else {\n <!-- Edit Form -->\n <div class=\"edit-panel\">\n <div class=\"edit-panel-header\">\n {{ editingIndex !== null ? 'Edit Entity Selector' : 'New Entity Selector' }}\n </div>\n <div class=\"edit-form\">\n <div class=\"form-field\">\n <label class=\"field-label\">ID *</label>\n <kendo-textbox\n [(ngModel)]=\"editId\"\n placeholder=\"e.g., mp\"\n [readonly]=\"editingIndex !== null\">\n </kendo-textbox>\n @if (isDuplicateId(editId, editingIndex)) {\n <span class=\"field-error\">ID must be unique</span>\n }\n <span class=\"field-hint\">Used in URL parameters (es_&lt;id&gt;=&lt;rtId&gt;)</span>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">Label *</label>\n <kendo-textbox\n [(ngModel)]=\"editLabel\"\n placeholder=\"e.g., Metering Point\">\n </kendo-textbox>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">CK Type *</label>\n <mm-ck-type-selector-input\n [ngModel]=\"editCkTypeItem\"\n [placeholder]=\"'Select CK type...'\"\n (ckTypeSelected)=\"onCkTypeSelected($event)\"\n (ckTypeCleared)=\"onCkTypeCleared()\">\n </mm-ck-type-selector-input>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">Attribute Mappings *</label>\n <button\n kendoButton\n (click)=\"selectAttributes()\"\n [disabled]=\"!editCkTypeId\"\n fillMode=\"outline\"\n size=\"small\">\n Select Attributes...\n </button>\n\n @if (editMappings.length > 0) {\n <div class=\"mappings-list\">\n <div class=\"mappings-header\">\n <span class=\"mappings-header-attr\">Attribute</span>\n <span class=\"mappings-header-var\">Variable Name</span>\n </div>\n @for (mapping of editMappings; track mapping.attributePath; let j = $index) {\n <div class=\"mapping-item\">\n <span class=\"mapping-path\">{{ mapping.attributePath }}</span>\n <span class=\"mapping-arrow\">&rarr;</span>\n <div class=\"mapping-var-field\">\n <div class=\"mapping-var-input-wrapper\">\n <span class=\"mapping-var-prefix\">$</span>\n <kendo-textbox\n [(ngModel)]=\"mapping.variableName\"\n size=\"small\"\n class=\"mapping-var-input\"\n placeholder=\"variableName\"\n [class.invalid]=\"getVariableNameError(mapping)\">\n </kendo-textbox>\n </div>\n @if (getVariableNameError(mapping); as error) {\n <span class=\"field-error\">{{ error }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"form-field\">\n <div class=\"checkbox-row\">\n <input\n type=\"checkbox\"\n kendoCheckBox\n [(ngModel)]=\"editShowInToolbar\"\n id=\"showInToolbar\" />\n <label class=\"field-label checkbox-label\" for=\"showInToolbar\">Show in Toolbar</label>\n </div>\n <span class=\"field-hint\">\n @if (editShowInToolbar) {\n Users can select an entity from a dropdown in the toolbar.\n } @else {\n Hidden selector \u2014 variables are resolved from the default entity below.\n }\n </span>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">Default Entity{{ !editShowInToolbar ? ' *' : '' }}</label>\n @if (defaultEntityDataSource) {\n <mm-entity-select-input\n [dataSource]=\"defaultEntityDataSource\"\n [dialogDataSource]=\"defaultEntityDialogDataSource!\"\n [placeholder]=\"'Select default entity...'\"\n [dialogTitle]=\"'Select Default ' + editLabel\"\n (entitySelected)=\"onDefaultEntitySelected($event)\"\n (entityCleared)=\"onDefaultEntityCleared()\">\n </mm-entity-select-input>\n } @else {\n <span class=\"field-hint\">Select a CK type first to pick a default entity.</span>\n }\n @if (editDefaultRtId) {\n <span class=\"field-hint\">Selected: {{ editDefaultRtId }}</span>\n }\n @if (!editShowInToolbar && !editDefaultRtId) {\n <span class=\"field-error\">A default entity is required when not shown in toolbar.</span>\n }\n <span class=\"field-hint\">\n @if (editShowInToolbar) {\n Optional \u2014 pre-selected entity when the MeshBoard loads.\n } @else {\n This entity's attributes will be used to populate the variables.\n }\n </span>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">Child Scope (stream-data)</label>\n <span class=\"field-hint\">\n Optional. Resolves the picked entity to its child source rtIds (one\n association hop) so a stream-data widget can scope to them \u2014 e.g. a\n MeteringPoint resolved to its EnergyMeasurement rtIds. Leave empty to\n scope by the picked entity's own rtId.\n </span>\n <mm-ck-type-selector-input\n [ngModel]=\"editChildScopeTargetCkTypeItem\"\n [placeholder]=\"'Child CK type (e.g. EnergyMeasurement)...'\"\n (ckTypeSelected)=\"onChildScopeCkTypeSelected($event)\"\n (ckTypeCleared)=\"onChildScopeCkTypeCleared()\">\n </mm-ck-type-selector-input>\n <kendo-textbox\n [(ngModel)]=\"editChildScopeRoleId\"\n placeholder=\"Association role (e.g. System/ParentChild)\">\n </kendo-textbox>\n <label class=\"field-label\">Direction</label>\n <select [(ngModel)]=\"editChildScopeDirection\" class=\"child-scope-direction\">\n <option value=\"out\">Outbound (parent \u2192 child)</option>\n <option value=\"in\">Inbound (child \u2192 parent)</option>\n </select>\n </div>\n\n <div class=\"edit-actions mm-dialog-actions\">\n <button kendoButton (click)=\"cancelEdit()\" fillMode=\"flat\">\n Cancel\n </button>\n <button\n kendoButton\n (click)=\"saveEdit()\"\n [disabled]=\"!isEditValid()\"\n themeColor=\"primary\">\n {{ editingIndex !== null ? 'Update' : 'Add' }}\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".entity-selector-editor{display:flex;flex-direction:column;gap:1.25rem}.selector-list{display:flex;flex-direction:column;gap:.5rem}.selector-item{display:flex;justify-content:space-between;align-items:center;padding:.75rem 1rem;background:var(--kendo-color-surface-alt, #fafafa);border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px}.selector-item .selector-info{display:flex;flex-direction:column;gap:.25rem;min-width:0;flex:1}.selector-item .selector-label{font-weight:500;color:var(--kendo-color-on-app-surface, #424242)}.selector-item .selector-mode{font-size:.75rem;font-weight:500;color:var(--kendo-color-info, #0288d1)}.selector-item .selector-ck-type{font-size:.8rem;color:var(--kendo-color-subtle, #757575);font-family:Consolas,Monaco,monospace}.selector-item .selector-mappings{font-size:.8rem;color:var(--kendo-color-primary, #3f51b5);font-family:Consolas,Monaco,monospace}.selector-item .selector-actions{display:flex;gap:.25rem;flex-shrink:0}.selector-item .remove-btn{color:var(--kendo-color-error, #f44336)}.empty-state{padding:1.5rem;text-align:center;color:var(--kendo-color-subtle, #757575);font-size:.875rem}.add-button-row{display:flex;justify-content:flex-start}.edit-panel{border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px;overflow:hidden}.edit-panel-header{padding:.625rem 1rem;font-weight:600;font-size:.875rem;color:var(--kendo-color-on-primary, #ffffff);background:var(--kendo-color-primary, #3f51b5)}.edit-form{display:flex;flex-direction:column;gap:1.25rem;padding:1.25rem}.edit-form .form-field{display:flex;flex-direction:column;gap:.5rem}.edit-form .field-label{font-weight:500;font-size:.875rem;text-transform:uppercase;color:var(--kendo-color-on-app-surface, #424242)}.edit-form .field-hint{font-size:.75rem;color:var(--kendo-color-subtle, #757575)}.edit-form .field-error{font-size:.75rem;color:var(--kendo-color-error, #f44336)}.edit-form .checkbox-row{display:flex;align-items:center;gap:.5rem}.edit-form .checkbox-row .checkbox-label{margin:0;cursor:pointer}.mappings-list{display:flex;flex-direction:column;gap:.5rem;margin-top:.5rem;padding:.75rem;background:var(--kendo-color-surface-alt, #fafafa);border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px}.mappings-header{display:flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--kendo-color-subtle, #757575);padding-bottom:.25rem;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.mappings-header .mappings-header-attr{min-width:150px}.mappings-header .mappings-header-var{margin-left:1.75rem}.mapping-item{display:flex;align-items:flex-start;gap:.5rem}.mapping-item .mapping-path{font-size:.8rem;font-family:Consolas,Monaco,monospace;color:var(--kendo-color-subtle, #757575);min-width:150px;padding-top:5px}.mapping-item .mapping-arrow{color:var(--kendo-color-subtle, #757575);flex-shrink:0;padding-top:5px}.mapping-item .mapping-var-field{display:flex;flex-direction:column;gap:2px;flex:1;min-width:100px}.mapping-item .mapping-var-input-wrapper{display:flex;align-items:center;gap:0}.mapping-item .mapping-var-prefix{font-family:Consolas,Monaco,monospace;font-size:.875rem;font-weight:600;color:var(--kendo-color-primary, #3f51b5);padding-right:2px;flex-shrink:0}.mapping-item .mapping-var-input{flex:1}.mapping-item .mapping-var-input.invalid ::ng-deep .k-input{border-color:var(--kendo-color-error, #f44336)}.edit-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:.5rem;padding-top:.75rem;border-top:1px solid var(--kendo-color-border, #e0e0e0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "ngmodule", type: LabelModule }, { kind: "directive", type: i4$1.LabelDirective, selector: "label[for]", inputs: ["for", "labelClass"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30615
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntitySelectorEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30616
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EntitySelectorEditorComponent, isStandalone: true, selector: "mm-entity-selector-editor", inputs: { entitySelectors: "entitySelectors", existingVariableNames: "existingVariableNames" }, outputs: { entitySelectorsChange: "entitySelectorsChange", editingStateChange: "editingStateChange" }, ngImport: i0, template: "<div class=\"entity-selector-editor\">\n @if (!isEditing) {\n <!-- Selector List -->\n <div class=\"selector-list\">\n @for (selector of entitySelectors; track selector.id; let i = $index) {\n <div class=\"selector-item\">\n <div class=\"selector-info\">\n <span class=\"selector-label\">{{ selector.label }}</span>\n <span class=\"selector-mode\">{{ getModeLabel(selector) }}</span>\n <span class=\"selector-ck-type\">{{ selector.ckTypeId }}</span>\n <span class=\"selector-mappings\">{{ getMappingSummary(selector) }}</span>\n </div>\n <div class=\"selector-actions\">\n <button\n kendoButton\n [svgIcon]=\"pencilIcon\"\n (click)=\"editSelector(i)\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Edit selector\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"trashIcon\"\n (click)=\"removeSelector(i)\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Remove selector\"\n class=\"remove-btn\">\n </button>\n </div>\n </div>\n }\n\n @if (entitySelectors.length === 0) {\n <div class=\"empty-state\">\n No entity selectors configured. Add one to enable entity-based variables.\n </div>\n }\n </div>\n\n <div class=\"add-button-row\">\n <button\n kendoButton\n [svgIcon]=\"plusIcon\"\n (click)=\"addSelector()\"\n themeColor=\"primary\">\n Add Entity Selector\n </button>\n </div>\n } @else {\n <!-- Edit Form -->\n <div class=\"edit-panel\">\n <div class=\"edit-panel-header\">\n {{ editingIndex !== null ? 'Edit Entity Selector' : 'New Entity Selector' }}\n </div>\n <div class=\"edit-form\">\n <div class=\"form-field\">\n <label class=\"field-label\">ID *</label>\n <kendo-textbox\n [(ngModel)]=\"editId\"\n placeholder=\"e.g., mp\"\n [readonly]=\"editingIndex !== null\">\n </kendo-textbox>\n @if (isDuplicateId(editId, editingIndex)) {\n <span class=\"field-error\">ID must be unique</span>\n }\n <span class=\"field-hint\">Used in URL parameters (es_&lt;id&gt;=&lt;rtId&gt;)</span>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">Label *</label>\n <kendo-textbox\n [(ngModel)]=\"editLabel\"\n placeholder=\"e.g., Metering Point\">\n </kendo-textbox>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">CK Type *</label>\n <mm-ck-type-selector-input\n [ngModel]=\"editCkTypeItem\"\n [placeholder]=\"'Select CK type...'\"\n (ckTypeSelected)=\"onCkTypeSelected($event)\"\n (ckTypeCleared)=\"onCkTypeCleared()\">\n </mm-ck-type-selector-input>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">Attribute Mappings *</label>\n <button\n kendoButton\n (click)=\"selectAttributes()\"\n [disabled]=\"!editCkTypeId\"\n fillMode=\"outline\"\n size=\"small\">\n Select Attributes...\n </button>\n\n @if (editMappings.length > 0) {\n <div class=\"mappings-list\">\n <div class=\"mappings-header\">\n <span class=\"mappings-header-attr\">Attribute</span>\n <span class=\"mappings-header-var\">Variable Name</span>\n </div>\n @for (mapping of editMappings; track mapping.attributePath; let j = $index) {\n <div class=\"mapping-item\">\n <span class=\"mapping-path\">{{ mapping.attributePath }}</span>\n <span class=\"mapping-arrow\">&rarr;</span>\n <div class=\"mapping-var-field\">\n <div class=\"mapping-var-input-wrapper\">\n <span class=\"mapping-var-prefix\">$</span>\n <kendo-textbox\n [(ngModel)]=\"mapping.variableName\"\n size=\"small\"\n class=\"mapping-var-input\"\n placeholder=\"variableName\"\n [class.invalid]=\"getVariableNameError(mapping)\">\n </kendo-textbox>\n </div>\n @if (getVariableNameError(mapping); as error) {\n <span class=\"field-error\">{{ error }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"form-field\">\n <div class=\"checkbox-row\">\n <input\n type=\"checkbox\"\n kendoCheckBox\n [(ngModel)]=\"editShowInToolbar\"\n id=\"showInToolbar\" />\n <label class=\"field-label checkbox-label\" for=\"showInToolbar\">Show in Toolbar</label>\n </div>\n <span class=\"field-hint\">\n @if (editShowInToolbar) {\n Users can select an entity from a dropdown in the toolbar.\n } @else {\n Hidden selector \u2014 variables are resolved from the default entity below.\n }\n </span>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">Default Entity{{ !editShowInToolbar ? ' *' : '' }}</label>\n @if (defaultEntityDataSource) {\n <mm-entity-select-input\n [dataSource]=\"defaultEntityDataSource\"\n [dialogDataSource]=\"defaultEntityDialogDataSource!\"\n [placeholder]=\"'Select default entity...'\"\n [dialogTitle]=\"'Select Default ' + editLabel\"\n (entitySelected)=\"onDefaultEntitySelected($event)\"\n (entityCleared)=\"onDefaultEntityCleared()\">\n </mm-entity-select-input>\n } @else {\n <span class=\"field-hint\">Select a CK type first to pick a default entity.</span>\n }\n @if (editDefaultRtId) {\n <span class=\"field-hint\">Selected: {{ editDefaultRtId }}</span>\n }\n @if (!editShowInToolbar && !editDefaultRtId) {\n <span class=\"field-error\">A default entity is required when not shown in toolbar.</span>\n }\n <span class=\"field-hint\">\n @if (editShowInToolbar) {\n Optional \u2014 pre-selected entity when the MeshBoard loads.\n } @else {\n This entity's attributes will be used to populate the variables.\n }\n </span>\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\">Child Scope (stream-data)</label>\n <span class=\"field-hint\">\n Optional. Resolves the picked entity to its child source rtIds (one\n association hop) so a stream-data widget can scope to them \u2014 e.g. a\n MeteringPoint resolved to its EnergyMeasurement rtIds. Leave empty to\n scope by the picked entity's own rtId.\n </span>\n <mm-ck-type-selector-input\n [ngModel]=\"editChildScopeTargetCkTypeItem\"\n [placeholder]=\"'Child CK type (e.g. EnergyMeasurement)...'\"\n (ckTypeSelected)=\"onChildScopeCkTypeSelected($event)\"\n (ckTypeCleared)=\"onChildScopeCkTypeCleared()\">\n </mm-ck-type-selector-input>\n <kendo-textbox\n [(ngModel)]=\"editChildScopeRoleId\"\n placeholder=\"Association role (e.g. System/ParentChild)\">\n </kendo-textbox>\n <label class=\"field-label\">Direction</label>\n <select [(ngModel)]=\"editChildScopeDirection\" class=\"child-scope-direction\">\n <option value=\"out\">Outbound (parent \u2192 child)</option>\n <option value=\"in\">Inbound (child \u2192 parent)</option>\n </select>\n </div>\n\n <div class=\"edit-actions mm-dialog-actions\">\n <button kendoButton (click)=\"cancelEdit()\" fillMode=\"flat\">\n Cancel\n </button>\n <button\n kendoButton\n (click)=\"saveEdit()\"\n [disabled]=\"!isEditValid()\"\n themeColor=\"primary\">\n {{ editingIndex !== null ? 'Update' : 'Add' }}\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".entity-selector-editor{display:flex;flex-direction:column;gap:1.25rem}.selector-list{display:flex;flex-direction:column;gap:.5rem}.selector-item{display:flex;justify-content:space-between;align-items:center;padding:.75rem 1rem;background:var(--kendo-color-surface-alt, #fafafa);border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px}.selector-item .selector-info{display:flex;flex-direction:column;gap:.25rem;min-width:0;flex:1}.selector-item .selector-label{font-weight:500;color:var(--kendo-color-on-app-surface, #424242)}.selector-item .selector-mode{font-size:.75rem;font-weight:500;color:var(--kendo-color-info, #0288d1)}.selector-item .selector-ck-type{font-size:.8rem;color:var(--kendo-color-subtle, #757575);font-family:Consolas,Monaco,monospace}.selector-item .selector-mappings{font-size:.8rem;color:var(--kendo-color-primary, #3f51b5);font-family:Consolas,Monaco,monospace}.selector-item .selector-actions{display:flex;gap:.25rem;flex-shrink:0}.selector-item .remove-btn{color:var(--kendo-color-error, #f44336)}.empty-state{padding:1.5rem;text-align:center;color:var(--kendo-color-subtle, #757575);font-size:.875rem}.add-button-row{display:flex;justify-content:flex-start}.edit-panel{border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px;overflow:hidden}.edit-panel-header{padding:.625rem 1rem;font-weight:600;font-size:.875rem;color:var(--kendo-color-on-primary, #ffffff);background:var(--kendo-color-primary, #3f51b5)}.edit-form{display:flex;flex-direction:column;gap:1.25rem;padding:1.25rem}.edit-form .form-field{display:flex;flex-direction:column;gap:.5rem}.edit-form .field-label{font-weight:500;font-size:.875rem;text-transform:uppercase;color:var(--kendo-color-on-app-surface, #424242)}.edit-form .field-hint{font-size:.75rem;color:var(--kendo-color-subtle, #757575)}.edit-form .field-error{font-size:.75rem;color:var(--kendo-color-error, #f44336)}.edit-form .checkbox-row{display:flex;align-items:center;gap:.5rem}.edit-form .checkbox-row .checkbox-label{margin:0;cursor:pointer}.mappings-list{display:flex;flex-direction:column;gap:.5rem;margin-top:.5rem;padding:.75rem;background:var(--kendo-color-surface-alt, #fafafa);border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px}.mappings-header{display:flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--kendo-color-subtle, #757575);padding-bottom:.25rem;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.mappings-header .mappings-header-attr{min-width:150px}.mappings-header .mappings-header-var{margin-left:1.75rem}.mapping-item{display:flex;align-items:flex-start;gap:.5rem}.mapping-item .mapping-path{font-size:.8rem;font-family:Consolas,Monaco,monospace;color:var(--kendo-color-subtle, #757575);min-width:150px;padding-top:5px}.mapping-item .mapping-arrow{color:var(--kendo-color-subtle, #757575);flex-shrink:0;padding-top:5px}.mapping-item .mapping-var-field{display:flex;flex-direction:column;gap:2px;flex:1;min-width:100px}.mapping-item .mapping-var-input-wrapper{display:flex;align-items:center;gap:0}.mapping-item .mapping-var-prefix{font-family:Consolas,Monaco,monospace;font-size:.875rem;font-weight:600;color:var(--kendo-color-primary, #3f51b5);padding-right:2px;flex-shrink:0}.mapping-item .mapping-var-input{flex:1}.mapping-item .mapping-var-input.invalid ::ng-deep .k-input{border-color:var(--kendo-color-error, #f44336)}.edit-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:.5rem;padding-top:.75rem;border-top:1px solid var(--kendo-color-border, #e0e0e0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple]):not([ngNoCva])[formControlName],select:not([multiple]):not([ngNoCva])[formControl],select:not([multiple]):not([ngNoCva])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "ngmodule", type: LabelModule }, { kind: "directive", type: i4$1.LabelDirective, selector: "label[for]", inputs: ["for", "labelClass"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "messages", "dialogMessages", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30078
30617
  }
30079
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntitySelectorEditorComponent, decorators: [{
30618
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntitySelectorEditorComponent, decorators: [{
30080
30619
  type: Component,
30081
30620
  args: [{ selector: 'mm-entity-selector-editor', standalone: true, imports: [
30082
30621
  CommonModule,
@@ -30158,10 +30697,10 @@ class EntitySelectorToolbarComponent {
30158
30697
  this.selectorDialogDataSources.set(selector.id, this.dialogDataSourceCache.get(selector.ckTypeId));
30159
30698
  }
30160
30699
  }
30161
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntitySelectorToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30162
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: EntitySelectorToolbarComponent, isStandalone: true, selector: "mm-entity-selector-toolbar", inputs: { entitySelectors: "entitySelectors" }, outputs: { entitySelected: "entitySelected", entityCleared: "entityCleared" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"entity-selector-toolbar\">\n @for (selector of entitySelectors; track selector.id) {\n @if (selector.showInToolbar !== false) {\n <div class=\"entity-selector-item\">\n <kendo-label [text]=\"selector.label\">\n <mm-entity-select-input\n [dataSource]=\"getDataSource(selector)\"\n [dialogDataSource]=\"getDialogDataSource(selector)\"\n [initialDisplayValue]=\"selector.selectedDisplayName\"\n [placeholder]=\"'Select ' + selector.label + '...'\"\n [dialogTitle]=\"'Select ' + selector.label\"\n (entitySelected)=\"onEntitySelected(selector.id, $event)\"\n (entityCleared)=\"onEntityCleared(selector.id)\">\n </mm-entity-select-input>\n </kendo-label>\n </div>\n }\n }\n</div>\n", styles: [".entity-selector-toolbar{display:flex;align-items:flex-end;gap:1rem;flex-wrap:wrap}.entity-selector-item{display:flex;flex-direction:column}.entity-selector-item kendo-label{display:flex;flex-direction:column;gap:.25rem}.entity-selector-item mm-entity-select-input{min-width:200px;max-width:300px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i4$1.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30700
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntitySelectorToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30701
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EntitySelectorToolbarComponent, isStandalone: true, selector: "mm-entity-selector-toolbar", inputs: { entitySelectors: "entitySelectors" }, outputs: { entitySelected: "entitySelected", entityCleared: "entityCleared" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"entity-selector-toolbar\">\n @for (selector of entitySelectors; track selector.id) {\n @if (selector.showInToolbar !== false) {\n <div class=\"entity-selector-item\">\n <kendo-label [text]=\"selector.label\">\n <mm-entity-select-input\n [dataSource]=\"getDataSource(selector)\"\n [dialogDataSource]=\"getDialogDataSource(selector)\"\n [initialDisplayValue]=\"selector.selectedDisplayName\"\n [placeholder]=\"'Select ' + selector.label + '...'\"\n [dialogTitle]=\"'Select ' + selector.label\"\n (entitySelected)=\"onEntitySelected(selector.id, $event)\"\n (entityCleared)=\"onEntityCleared(selector.id)\">\n </mm-entity-select-input>\n </kendo-label>\n </div>\n }\n }\n</div>\n", styles: [".entity-selector-toolbar{display:flex;align-items:flex-end;gap:1rem;flex-wrap:wrap}.entity-selector-item{display:flex;flex-direction:column}.entity-selector-item kendo-label{display:flex;flex-direction:column;gap:.25rem}.entity-selector-item mm-entity-select-input{min-width:200px;max-width:300px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i4$1.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "component", type: EntitySelectInputComponent, selector: "mm-entity-select-input", inputs: ["dataSource", "placeholder", "minSearchLength", "maxResults", "debounceMs", "prefix", "initialDisplayValue", "dialogDataSource", "dialogTitle", "multiSelect", "advancedSearchLabel", "dialogMessages", "messages", "disabled", "required"], outputs: ["entitySelected", "entityCleared", "entitiesSelected"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30163
30702
  }
30164
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EntitySelectorToolbarComponent, decorators: [{
30703
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntitySelectorToolbarComponent, decorators: [{
30165
30704
  type: Component,
30166
30705
  args: [{ selector: 'mm-entity-selector-toolbar', standalone: true, imports: [
30167
30706
  CommonModule,
@@ -30307,10 +30846,10 @@ class VariablesEditorComponent {
30307
30846
  emitChange() {
30308
30847
  this.variablesChange.emit([...this.variables]);
30309
30848
  }
30310
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: VariablesEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30311
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: VariablesEditorComponent, isStandalone: true, selector: "mm-variables-editor", inputs: { variables: "variables" }, outputs: { variablesChange: "variablesChange" }, ngImport: i0, template: "<div class=\"variables-editor\">\n <div class=\"variables-header\">\n <span class=\"section-title\">Variables</span>\n <div class=\"header-actions\">\n <button\n kendoButton\n (click)=\"addVariable()\"\n [svgIcon]=\"plusIcon\"\n themeColor=\"primary\">\n Add Variable\n </button>\n </div>\n </div>\n\n @if (variables.length > 0) {\n <div class=\"variables-list\">\n <div class=\"list-header\">\n <span class=\"col-name\">Name</span>\n <span class=\"col-config\">Configuration</span>\n <span class=\"col-actions\"></span>\n </div>\n\n @for (variable of variables; track trackByIndex($index); let i = $index) {\n <div class=\"variable-row\">\n <!-- Name -->\n <div class=\"col-name\">\n <kendo-textbox\n [value]=\"variable.name\"\n (valueChange)=\"onNameChange(i, $event)\"\n placeholder=\"variableName\"\n [style.width.%]=\"100\">\n </kendo-textbox>\n @if (!isValidName(variable.name)) {\n <span class=\"error-text\">Invalid name</span>\n }\n @if (isDuplicateName(variable.name, i)) {\n <span class=\"error-text\">Duplicate</span>\n }\n </div>\n\n <!-- Configuration (type-specific) -->\n <div class=\"col-config\">\n <div class=\"static-config\">\n <div class=\"static-config-row\">\n <kendo-dropdownlist\n [data]=\"typeOptions\"\n [value]=\"getTypeOption(variable)\"\n (valueChange)=\"onTypeChange(i, $event.value)\"\n textField=\"label\"\n valueField=\"value\"\n class=\"type-dropdown\">\n </kendo-dropdownlist>\n\n @switch (variable.type) {\n @case ('number') {\n <kendo-numerictextbox\n [value]=\"getNumberValue(variable)\"\n (valueChange)=\"onNumberValueChange(i, $event)\"\n class=\"value-input\">\n </kendo-numerictextbox>\n }\n @case ('boolean') {\n <kendo-dropdownlist\n [data]=\"booleanOptions\"\n [value]=\"variable.value\"\n (valueChange)=\"onValueChange(i, $event)\"\n class=\"value-input\">\n </kendo-dropdownlist>\n }\n @case ('date') {\n <kendo-datepicker\n [value]=\"getDateValue(variable)\"\n (valueChange)=\"onDateValueChange(i, $event)\"\n class=\"value-input\">\n </kendo-datepicker>\n }\n @case ('datetime') {\n <kendo-datetimepicker\n [value]=\"getDateValue(variable)\"\n (valueChange)=\"onDateValueChange(i, $event)\"\n class=\"value-input\">\n </kendo-datetimepicker>\n }\n @default {\n <kendo-textbox\n [value]=\"variable.value\"\n (valueChange)=\"onValueChange(i, $event)\"\n placeholder=\"Value\"\n class=\"value-input\">\n </kendo-textbox>\n }\n }\n\n <kendo-textbox\n [value]=\"variable.defaultValue ?? ''\"\n (valueChange)=\"onDefaultValueChange(i, $event)\"\n placeholder=\"Default\"\n class=\"default-input\">\n </kendo-textbox>\n </div>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"col-actions\">\n <button\n kendoButton\n (click)=\"removeVariable(i)\"\n [svgIcon]=\"trashIcon\"\n fillMode=\"flat\"\n themeColor=\"error\"\n title=\"Remove variable\">\n </button>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <p>No variables defined.</p>\n <p class=\"hint\">Click \"Add Variable\" to create one. Use Entity Selectors for entity-based variables.</p>\n </div>\n }\n\n <div class=\"usage-hint\">\n <strong>Usage:</strong> Reference variables in filter values as <code>{{ '${variableName}' }}</code>\n </div>\n</div>\n", styles: [".variables-editor{margin-top:1rem}.variables-editor .variables-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.variables-editor .variables-header .section-title{font-weight:600;font-size:14px;color:var(--kendo-color-on-app-surface, #424242)}.variables-editor .variables-header .header-actions{display:flex;gap:4px}.variables-editor .variables-list{border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px;background:var(--kendo-color-surface-alt, #fafafa)}.variables-editor .variables-list .list-header{display:grid;grid-template-columns:180px 1fr 40px;gap:.5rem;padding:.5rem .75rem;background:var(--kendo-color-surface, #f5f5f5);border-bottom:1px solid var(--kendo-color-border, #e0e0e0);font-size:12px;font-weight:600;color:var(--kendo-color-subtle, #666)}.variables-editor .variables-list .variable-row{display:grid;grid-template-columns:180px 1fr 40px;gap:.5rem;padding:.5rem .75rem;align-items:start;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.variables-editor .variables-list .variable-row:last-child{border-bottom:none}.variables-editor .variables-list .variable-row .col-name{display:flex;flex-direction:column;gap:2px}.variables-editor .variables-list .variable-row .col-config{display:flex;flex-direction:column;gap:4px}.variables-editor .variables-list .variable-row .col-actions{display:flex;justify-content:center;gap:2px;padding-top:2px}.variables-editor .variables-list .variable-row .error-text{font-size:11px;color:var(--kendo-color-error, #f44336)}.variables-editor .variables-list .variable-row .static-config-row{display:flex;gap:.5rem;align-items:start}.variables-editor .variables-list .variable-row .static-config-row .type-dropdown{width:110px;flex-shrink:0}.variables-editor .variables-list .variable-row .static-config-row .value-input{flex:1;min-width:0}.variables-editor .variables-list .variable-row .static-config-row .default-input{width:120px;flex-shrink:0}.variables-editor .empty-state{padding:2rem;text-align:center;color:var(--kendo-color-subtle, #666);background:var(--kendo-color-surface-alt, #fafafa);border:1px dashed var(--kendo-color-border, #ccc);border-radius:4px}.variables-editor .empty-state p{margin:.25rem 0}.variables-editor .empty-state .hint{font-size:12px;color:var(--kendo-color-subtle, #999)}.variables-editor .usage-hint{margin-top:.75rem;padding:.5rem .75rem;background:var(--kendo-color-surface-alt, #e3f2fd);border:1px solid var(--kendo-color-border, transparent);border-radius:4px;font-size:12px;color:var(--kendo-color-subtle, #1565c0)}.variables-editor .usage-hint code{background:var(--kendo-color-base-subtle, #bbdefb);padding:2px 6px;border-radius:3px;font-family:Consolas,Monaco,monospace}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DropDownListModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: NumericTextBoxModule }, { kind: "ngmodule", type: TextBoxModule }, { kind: "ngmodule", type: CheckBoxModule }, { kind: "ngmodule", type: DatePickerModule }, { kind: "component", type: i4$2.DatePickerComponent, selector: "kendo-datepicker", inputs: ["focusableId", "cellTemplate", "clearButton", "inputAttributes", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "headerTemplate", "footerTemplate", "footer", "navigationItemTemplate", "weekDaysFormat", "showOtherMonthDays", "activeView", "bottomView", "topView", "calendarType", "animateCalendarNavigation", "disabled", "readonly", "readOnlyInput", "popupSettings", "navigation", "min", "max", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "autoFill", "focusedDate", "value", "format", "twoDigitYearMax", "formatPlaceholder", "placeholder", "tabindex", "tabIndex", "disabledDates", "adaptiveTitle", "adaptiveSubtitle", "rangeValidation", "disabledDatesValidation", "weekNumber", "size", "rounded", "fillMode", "adaptiveMode"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-datepicker"] }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "component", type: i4$2.DateTimePickerComponent, selector: "kendo-datetimepicker", inputs: ["focusableId", "weekDaysFormat", "showOtherMonthDays", "value", "format", "twoDigitYearMax", "tabindex", "disabledDates", "popupSettings", "adaptiveTitle", "adaptiveSubtitle", "disabled", "readonly", "readOnlyInput", "cancelButton", "formatPlaceholder", "placeholder", "steps", "focusedDate", "calendarType", "animateCalendarNavigation", "weekNumber", "min", "max", "rangeValidation", "disabledDatesValidation", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "clearButton", "autoFill", "adaptiveMode", "inputAttributes", "defaultTab", "size", "rounded", "fillMode", "headerTemplate", "footerTemplate", "footer"], outputs: ["valueChange", "open", "close", "focus", "blur", "escape"], exportAs: ["kendo-datetimepicker"] }, { kind: "ngmodule", type: SVGIconModule }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30849
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: VariablesEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30850
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: VariablesEditorComponent, isStandalone: true, selector: "mm-variables-editor", inputs: { variables: "variables" }, outputs: { variablesChange: "variablesChange" }, ngImport: i0, template: "<div class=\"variables-editor\">\n <div class=\"variables-header\">\n <span class=\"section-title\">Variables</span>\n <div class=\"header-actions\">\n <button\n kendoButton\n (click)=\"addVariable()\"\n [svgIcon]=\"plusIcon\"\n themeColor=\"primary\">\n Add Variable\n </button>\n </div>\n </div>\n\n @if (variables.length > 0) {\n <div class=\"variables-list\">\n <div class=\"list-header\">\n <span class=\"col-name\">Name</span>\n <span class=\"col-config\">Configuration</span>\n <span class=\"col-actions\"></span>\n </div>\n\n @for (variable of variables; track trackByIndex($index); let i = $index) {\n <div class=\"variable-row\">\n <!-- Name -->\n <div class=\"col-name\">\n <kendo-textbox\n [value]=\"variable.name\"\n (valueChange)=\"onNameChange(i, $event)\"\n placeholder=\"variableName\"\n [style.width.%]=\"100\">\n </kendo-textbox>\n @if (!isValidName(variable.name)) {\n <span class=\"error-text\">Invalid name</span>\n }\n @if (isDuplicateName(variable.name, i)) {\n <span class=\"error-text\">Duplicate</span>\n }\n </div>\n\n <!-- Configuration (type-specific) -->\n <div class=\"col-config\">\n <div class=\"static-config\">\n <div class=\"static-config-row\">\n <kendo-dropdownlist\n [data]=\"typeOptions\"\n [value]=\"getTypeOption(variable)\"\n (valueChange)=\"onTypeChange(i, $event.value)\"\n textField=\"label\"\n valueField=\"value\"\n class=\"type-dropdown\">\n </kendo-dropdownlist>\n\n @switch (variable.type) {\n @case ('number') {\n <kendo-numerictextbox\n [value]=\"getNumberValue(variable)\"\n (valueChange)=\"onNumberValueChange(i, $event)\"\n class=\"value-input\">\n </kendo-numerictextbox>\n }\n @case ('boolean') {\n <kendo-dropdownlist\n [data]=\"booleanOptions\"\n [value]=\"variable.value\"\n (valueChange)=\"onValueChange(i, $event)\"\n class=\"value-input\">\n </kendo-dropdownlist>\n }\n @case ('date') {\n <kendo-datepicker\n [value]=\"getDateValue(variable)\"\n (valueChange)=\"onDateValueChange(i, $event)\"\n class=\"value-input\">\n </kendo-datepicker>\n }\n @case ('datetime') {\n <kendo-datetimepicker\n [value]=\"getDateValue(variable)\"\n (valueChange)=\"onDateValueChange(i, $event)\"\n class=\"value-input\">\n </kendo-datetimepicker>\n }\n @default {\n <kendo-textbox\n [value]=\"variable.value\"\n (valueChange)=\"onValueChange(i, $event)\"\n placeholder=\"Value\"\n class=\"value-input\">\n </kendo-textbox>\n }\n }\n\n <kendo-textbox\n [value]=\"variable.defaultValue ?? ''\"\n (valueChange)=\"onDefaultValueChange(i, $event)\"\n placeholder=\"Default\"\n class=\"default-input\">\n </kendo-textbox>\n </div>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"col-actions\">\n <button\n kendoButton\n (click)=\"removeVariable(i)\"\n [svgIcon]=\"trashIcon\"\n fillMode=\"flat\"\n themeColor=\"error\"\n title=\"Remove variable\">\n </button>\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-state\">\n <p>No variables defined.</p>\n <p class=\"hint\">Click \"Add Variable\" to create one. Use Entity Selectors for entity-based variables.</p>\n </div>\n }\n\n <div class=\"usage-hint\">\n <strong>Usage:</strong> Reference variables in filter values as <code>{{ '${variableName}' }}</code>\n </div>\n</div>\n", styles: [".variables-editor{margin-top:1rem}.variables-editor .variables-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.variables-editor .variables-header .section-title{font-weight:600;font-size:14px;color:var(--kendo-color-on-app-surface, #424242)}.variables-editor .variables-header .header-actions{display:flex;gap:4px}.variables-editor .variables-list{border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px;background:var(--kendo-color-surface-alt, #fafafa)}.variables-editor .variables-list .list-header{display:grid;grid-template-columns:180px 1fr 40px;gap:.5rem;padding:.5rem .75rem;background:var(--kendo-color-surface, #f5f5f5);border-bottom:1px solid var(--kendo-color-border, #e0e0e0);font-size:12px;font-weight:600;color:var(--kendo-color-subtle, #666)}.variables-editor .variables-list .variable-row{display:grid;grid-template-columns:180px 1fr 40px;gap:.5rem;padding:.5rem .75rem;align-items:start;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.variables-editor .variables-list .variable-row:last-child{border-bottom:none}.variables-editor .variables-list .variable-row .col-name{display:flex;flex-direction:column;gap:2px}.variables-editor .variables-list .variable-row .col-config{display:flex;flex-direction:column;gap:4px}.variables-editor .variables-list .variable-row .col-actions{display:flex;justify-content:center;gap:2px;padding-top:2px}.variables-editor .variables-list .variable-row .error-text{font-size:11px;color:var(--kendo-color-error, #f44336)}.variables-editor .variables-list .variable-row .static-config-row{display:flex;gap:.5rem;align-items:start}.variables-editor .variables-list .variable-row .static-config-row .type-dropdown{width:110px;flex-shrink:0}.variables-editor .variables-list .variable-row .static-config-row .value-input{flex:1;min-width:0}.variables-editor .variables-list .variable-row .static-config-row .default-input{width:120px;flex-shrink:0}.variables-editor .empty-state{padding:2rem;text-align:center;color:var(--kendo-color-subtle, #666);background:var(--kendo-color-surface-alt, #fafafa);border:1px dashed var(--kendo-color-border, #ccc);border-radius:4px}.variables-editor .empty-state p{margin:.25rem 0}.variables-editor .empty-state .hint{font-size:12px;color:var(--kendo-color-subtle, #999)}.variables-editor .usage-hint{margin-top:.75rem;padding:.5rem .75rem;background:var(--kendo-color-surface-alt, #e3f2fd);border:1px solid var(--kendo-color-border, transparent);border-radius:4px;font-size:12px;color:var(--kendo-color-subtle, #1565c0)}.variables-editor .usage-hint code{background:var(--kendo-color-base-subtle, #bbdefb);padding:2px 6px;border-radius:3px;font-family:Consolas,Monaco,monospace}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DropDownListModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: NumericTextBoxModule }, { kind: "ngmodule", type: TextBoxModule }, { kind: "ngmodule", type: CheckBoxModule }, { kind: "ngmodule", type: DatePickerModule }, { kind: "component", type: i4$2.DatePickerComponent, selector: "kendo-datepicker", inputs: ["focusableId", "cellTemplate", "clearButton", "inputAttributes", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "headerTemplate", "footerTemplate", "footer", "navigationItemTemplate", "weekDaysFormat", "showOtherMonthDays", "activeView", "bottomView", "topView", "calendarType", "animateCalendarNavigation", "disabled", "readonly", "readOnlyInput", "popupSettings", "navigation", "min", "max", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "autoFill", "focusedDate", "value", "format", "twoDigitYearMax", "formatPlaceholder", "placeholder", "tabindex", "tabIndex", "disabledDates", "adaptiveTitle", "adaptiveSubtitle", "rangeValidation", "disabledDatesValidation", "weekNumber", "size", "rounded", "fillMode", "adaptiveMode"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-datepicker"] }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "component", type: i4$2.DateTimePickerComponent, selector: "kendo-datetimepicker", inputs: ["focusableId", "weekDaysFormat", "showOtherMonthDays", "value", "format", "twoDigitYearMax", "tabindex", "disabledDates", "popupSettings", "adaptiveTitle", "adaptiveSubtitle", "disabled", "readonly", "readOnlyInput", "cancelButton", "formatPlaceholder", "placeholder", "steps", "focusedDate", "calendarType", "animateCalendarNavigation", "weekNumber", "min", "max", "rangeValidation", "disabledDatesValidation", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "clearButton", "autoFill", "adaptiveMode", "inputAttributes", "defaultTab", "size", "rounded", "fillMode", "headerTemplate", "footerTemplate", "footer"], outputs: ["valueChange", "open", "close", "focus", "blur", "escape"], exportAs: ["kendo-datetimepicker"] }, { kind: "ngmodule", type: SVGIconModule }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30312
30851
  }
30313
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: VariablesEditorComponent, decorators: [{
30852
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: VariablesEditorComponent, decorators: [{
30314
30853
  type: Component,
30315
30854
  args: [{ selector: 'mm-variables-editor', standalone: true, imports: [
30316
30855
  CommonModule,
@@ -30390,6 +30929,38 @@ class MeshBoardSettingsDialogComponent {
30390
30929
  * widgets. Defaults to `'local'` (browser timezone).
30391
30930
  */
30392
30931
  timeZoneMode = DEFAULT_TIME_ZONE_MODE;
30932
+ /**
30933
+ * Curated IANA zones offered in the "Specific time zone" picker (AB#4190). Not exhaustive —
30934
+ * a board can hold any IANA id; this is the convenient shortlist shown in the settings UI.
30935
+ */
30936
+ commonTimeZones = [
30937
+ 'Europe/Vienna',
30938
+ 'Europe/Berlin',
30939
+ 'Europe/Lisbon',
30940
+ 'Europe/London',
30941
+ 'Europe/Istanbul',
30942
+ 'America/New_York',
30943
+ 'America/Sao_Paulo',
30944
+ 'America/Los_Angeles',
30945
+ 'Asia/Shanghai',
30946
+ 'Asia/Tokyo',
30947
+ 'Australia/Sydney'
30948
+ ];
30949
+ /** The IANA id bound to the picker; only applied to {@link timeZoneMode} while "Specific time zone" is selected. */
30950
+ zoneSelection = 'Europe/Vienna';
30951
+ /** True when the board zone is an explicit IANA id (i.e. neither `'local'` nor `'utc'`). */
30952
+ get isSpecificZone() {
30953
+ return this.timeZoneMode !== 'local' && this.timeZoneMode !== 'utc';
30954
+ }
30955
+ /** Selects the "Specific time zone" option, applying the currently-picked IANA id. */
30956
+ selectSpecificZone() {
30957
+ this.timeZoneMode = this.zoneSelection;
30958
+ }
30959
+ /** Handles a change in the IANA dropdown; keeps {@link timeZoneMode} in sync while that option is active. */
30960
+ onZoneSelectionChange(zone) {
30961
+ this.zoneSelection = zone;
30962
+ this.timeZoneMode = zone;
30963
+ }
30393
30964
  /** Static and time filter variable names for duplicate detection in entity selector editor */
30394
30965
  get staticVariableNames() {
30395
30966
  return this.variables
@@ -30416,6 +30987,13 @@ class MeshBoardSettingsDialogComponent {
30416
30987
  this.gap = settings.gap;
30417
30988
  this.autoRefreshSeconds = settings.autoRefreshSeconds ?? 0;
30418
30989
  this.timeZoneMode = settings.timeZoneMode ?? DEFAULT_TIME_ZONE_MODE;
30990
+ if (this.isSpecificZone) {
30991
+ // Seed the picker with the persisted IANA id; add it to the shortlist if custom.
30992
+ this.zoneSelection = this.timeZoneMode;
30993
+ if (!this.commonTimeZones.includes(this.timeZoneMode)) {
30994
+ this.commonTimeZones.unshift(this.timeZoneMode);
30995
+ }
30996
+ }
30419
30997
  this.variables = settings.variables ? [...settings.variables] : [];
30420
30998
  this.entitySelectors = settings.entitySelectors ? settings.entitySelectors.map(es => ({ ...es })) : [];
30421
30999
  this.timeFilterEnabled = settings.timeFilter?.enabled ?? false;
@@ -30466,10 +31044,10 @@ class MeshBoardSettingsDialogComponent {
30466
31044
  cancel() {
30467
31045
  this.windowRef.close();
30468
31046
  }
30469
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardSettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30470
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: MeshBoardSettingsDialogComponent, isStandalone: true, selector: "mm-meshboard-settings-dialog", ngImport: i0, template: "<div class=\"meshboard-settings-dialog\">\n <kendo-tabstrip [animate]=\"false\">\n <!-- General Tab -->\n <kendo-tabstrip-tab [title]=\"'General'\" [selected]=\"true\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <form class=\"settings-form\">\n <!-- Name Field -->\n <kendo-formfield>\n <kendo-label [for]=\"nameInput\" text=\"Name *\"></kendo-label>\n <kendo-textbox\n #nameInput\n [(ngModel)]=\"name\"\n name=\"name\"\n placeholder=\"Enter MeshBoard name\"\n required>\n </kendo-textbox>\n @if (name.trim().length === 0) {\n <kendo-formerror>Name is required</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Description Field -->\n <kendo-formfield>\n <kendo-label [for]=\"descriptionInput\" text=\"Description\"></kendo-label>\n <kendo-textarea\n #descriptionInput\n [(ngModel)]=\"description\"\n name=\"description\"\n placeholder=\"Enter MeshBoard description (optional)\"\n [rows]=\"3\">\n </kendo-textarea>\n </kendo-formfield>\n\n <!-- Well-Known Name Field -->\n <kendo-formfield>\n <kendo-label [for]=\"wellKnownNameInput\" text=\"Well-Known Name\"></kendo-label>\n <kendo-textbox\n #wellKnownNameInput\n [(ngModel)]=\"rtWellKnownName\"\n name=\"rtWellKnownName\"\n placeholder=\"e.g., cockpit, dashboard-main\">\n </kendo-textbox>\n <kendo-formhint>Unique identifier for routing. Use lowercase with hyphens (e.g., 'cockpit', 'sales-dashboard').</kendo-formhint>\n </kendo-formfield>\n\n <!-- Layout Settings -->\n <div class=\"section-title\">Layout Settings</div>\n\n <!-- Columns Field -->\n <kendo-formfield>\n <kendo-label [for]=\"columnsInput\" text=\"Columns *\"></kendo-label>\n <kendo-numerictextbox\n #columnsInput\n [(ngModel)]=\"columns\"\n name=\"columns\"\n [min]=\"1\"\n [max]=\"12\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Number of columns in the grid (1-12)</kendo-formhint>\n @if (columns < 1 || columns > 12) {\n <kendo-formerror>Columns must be between 1 and 12</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Row Height Field -->\n <kendo-formfield>\n <kendo-label [for]=\"rowHeightInput\" text=\"Row Height *\"></kendo-label>\n <kendo-numerictextbox\n #rowHeightInput\n [(ngModel)]=\"rowHeight\"\n name=\"rowHeight\"\n [min]=\"100\"\n [max]=\"1000\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Height of each row in pixels (100-1000)</kendo-formhint>\n @if (rowHeight < 100 || rowHeight > 1000) {\n <kendo-formerror>Row height must be between 100 and 1000</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Gap Field -->\n <kendo-formfield>\n <kendo-label [for]=\"gapInput\" text=\"Gap *\"></kendo-label>\n <kendo-numerictextbox\n #gapInput\n [(ngModel)]=\"gap\"\n name=\"gap\"\n [min]=\"0\"\n [max]=\"100\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Space between widgets in pixels (0-100)</kendo-formhint>\n @if (gap < 0 || gap > 100) {\n <kendo-formerror>Gap must be between 0 and 100</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Auto-Refresh Field -->\n <kendo-formfield>\n <kendo-label [for]=\"autoRefreshInput\" text=\"Auto-refresh\"></kendo-label>\n <kendo-numerictextbox\n #autoRefreshInput\n [(ngModel)]=\"autoRefreshSeconds\"\n name=\"autoRefreshSeconds\"\n [min]=\"0\"\n [max]=\"3600\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\">\n </kendo-numerictextbox>\n <kendo-formhint>Refresh interval in seconds (0 = disabled, max 3600). Pauses while the tab is hidden.</kendo-formhint>\n @if (autoRefreshSeconds < 0 || autoRefreshSeconds > 3600) {\n <kendo-formerror>Auto-refresh must be between 0 and 3600 seconds</kendo-formerror>\n }\n </kendo-formfield>\n </form>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Variables Tab -->\n <kendo-tabstrip-tab [title]=\"'Variables'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <mm-variables-editor\n [(variables)]=\"variables\">\n </mm-variables-editor>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Time Filter Tab -->\n <kendo-tabstrip-tab [title]=\"'Time Filter'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <form class=\"settings-form\">\n <kendo-formfield>\n <kendo-label text=\"Timezone\"></kendo-label>\n <div class=\"radio-group\">\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzLocal\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n value=\"local\"\n id=\"timeZoneModeLocal\"/>\n <kendo-label [for]=\"tzLocal\" text=\"Local time (browser)\" class=\"radio-label\"></kendo-label>\n </div>\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzUtc\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n value=\"utc\"\n id=\"timeZoneModeUtc\"/>\n <kendo-label [for]=\"tzUtc\" text=\"UTC\" class=\"radio-label\"></kendo-label>\n </div>\n </div>\n <kendo-formhint>\n Basis for the time filter and for how all widgets display dates and times. Local time is the default.\n </kendo-formhint>\n </kendo-formfield>\n\n <kendo-formfield>\n <div class=\"checkbox-wrapper\">\n <input\n type=\"checkbox\"\n kendoCheckBox\n #timeFilterCheckbox\n [(ngModel)]=\"timeFilterEnabled\"\n name=\"timeFilterEnabled\"\n id=\"timeFilterEnabled\"/>\n <kendo-label\n [for]=\"timeFilterCheckbox\"\n text=\"Enable Time Filter\"\n class=\"checkbox-label\">\n </kendo-label>\n </div>\n <kendo-formhint>\n Shows a time range picker in the toolbar. Sets $timeRangeFrom and $timeRangeTo variables.\n </kendo-formhint>\n </kendo-formfield>\n\n @if (timeFilterEnabled) {\n <kendo-formfield>\n <kendo-label text=\"Default Selection\"></kendo-label>\n <mm-time-range-picker\n [initialSelection]=\"initialDefaultSelection\"\n (selectionChange)=\"onDefaultSelectionChange($event)\">\n </mm-time-range-picker>\n <kendo-formhint>Initial time filter shown when no URL parameters are set. Note: User-selected filters override this default. Use the reset button in the toolbar to revert to the default.</kendo-formhint>\n </kendo-formfield>\n }\n </form>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Entity Selectors Tab -->\n <kendo-tabstrip-tab [title]=\"'Entity Selectors'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <mm-entity-selector-editor\n [(entitySelectors)]=\"entitySelectors\"\n [existingVariableNames]=\"staticVariableNames\"\n (editingStateChange)=\"entitySelectorEditing = $event\">\n </mm-entity-selector-editor>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n </kendo-tabstrip>\n\n <!-- Dialog Actions -->\n @if (!entitySelectorEditing) {\n <div class=\"dialog-actions mm-dialog-actions\">\n <button kendoButton (click)=\"cancel()\" fillMode=\"flat\">\n Cancel\n </button>\n <button\n kendoButton\n (click)=\"save()\"\n [disabled]=\"!isValid\"\n themeColor=\"primary\">\n Save\n </button>\n </div>\n }\n</div>\n", styles: [".meshboard-settings-dialog{display:flex;flex-direction:column;height:100%;overflow:hidden}.meshboard-settings-dialog kendo-tabstrip{flex:1;min-height:0;display:flex;flex-direction:column}.meshboard-settings-dialog kendo-tabstrip ::ng-deep .k-tabstrip-content{flex:1;min-height:0;overflow:hidden}.meshboard-settings-dialog .tab-content{height:100%;overflow-y:auto;padding:1.5rem}.meshboard-settings-dialog .settings-form{display:flex;flex-direction:column;gap:1.25rem}.meshboard-settings-dialog .settings-form kendo-formfield{display:flex;flex-direction:column;gap:.5rem}.meshboard-settings-dialog .settings-form kendo-formfield kendo-label{font-weight:500;color:var(--kendo-color-on-app-surface, #424242)}.meshboard-settings-dialog .settings-form kendo-formfield kendo-textbox,.meshboard-settings-dialog .settings-form kendo-formfield kendo-textarea,.meshboard-settings-dialog .settings-form kendo-formfield kendo-numerictextbox{width:100%}.meshboard-settings-dialog .settings-form kendo-formfield kendo-formhint{font-size:.75rem;color:var(--kendo-color-subtle, #757575)}.meshboard-settings-dialog .settings-form kendo-formfield kendo-formerror{font-size:.75rem;color:var(--kendo-color-error, #f44336)}.meshboard-settings-dialog .settings-form .section-title{font-size:.875rem;font-weight:600;color:var(--kendo-color-on-app-surface, #424242);text-transform:uppercase;letter-spacing:.5px;margin-top:.5rem;padding-bottom:.5rem;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.meshboard-settings-dialog .settings-form .checkbox-wrapper,.meshboard-settings-dialog .settings-form .radio-wrapper{display:flex;align-items:center;gap:.5rem}.meshboard-settings-dialog .settings-form .checkbox-wrapper .checkbox-label,.meshboard-settings-dialog .settings-form .checkbox-wrapper .radio-label,.meshboard-settings-dialog .settings-form .radio-wrapper .checkbox-label,.meshboard-settings-dialog .settings-form .radio-wrapper .radio-label{font-weight:400;cursor:pointer}.meshboard-settings-dialog .settings-form .radio-group{display:flex;flex-direction:column;gap:.5rem;margin-top:.25rem}.meshboard-settings-dialog .dialog-actions{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--kendo-color-border, #e0e0e0);flex-shrink:0;background-color:var(--kendo-color-surface-alt, white)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "component", type: i3.TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "directive", type: i3.RadioButtonDirective, selector: "input[kendoRadioButton]", inputs: ["size"] }, { kind: "component", type: i3.FormFieldComponent, selector: "kendo-formfield", inputs: ["showHints", "orientation", "showErrors", "colSpan"] }, { kind: "component", type: i3.HintComponent, selector: "kendo-formhint", inputs: ["align"] }, { kind: "component", type: i3.ErrorComponent, selector: "kendo-formerror", inputs: ["align"] }, { kind: "ngmodule", type: CheckBoxModule }, { kind: "ngmodule", type: LabelModule }, { kind: "component", type: i4$1.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "ngmodule", type: FormFieldModule }, { kind: "ngmodule", type: TabStripModule }, { kind: "component", type: i5.TabStripComponent, selector: "kendo-tabstrip", inputs: ["height", "animate", "tabAlignment", "tabPosition", "keepTabContent", "closable", "scrollable", "size", "closeIcon", "closeIconClass", "closeSVGIcon", "showContentArea"], outputs: ["tabSelect", "tabClose", "tabScroll"], exportAs: ["kendoTabStrip"] }, { kind: "component", type: i5.TabStripTabComponent, selector: "kendo-tabstrip-tab", inputs: ["title", "disabled", "cssClass", "cssStyle", "selected", "closable", "closeIcon", "closeIconClass", "closeSVGIcon"], exportAs: ["kendoTabStripTab"] }, { kind: "directive", type: i5.TabContentDirective, selector: "[kendoTabContent]" }, { kind: "component", type: VariablesEditorComponent, selector: "mm-variables-editor", inputs: ["variables"], outputs: ["variablesChange"] }, { kind: "component", type: EntitySelectorEditorComponent, selector: "mm-entity-selector-editor", inputs: ["entitySelectors", "existingVariableNames"], outputs: ["entitySelectorsChange", "editingStateChange"] }, { kind: "component", type: TimeRangePickerComponent, selector: "mm-time-range-picker", inputs: ["config", "labels", "initialSelection"], outputs: ["rangeChange", "rangeChangeISO", "selectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
31047
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardSettingsDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31048
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: MeshBoardSettingsDialogComponent, isStandalone: true, selector: "mm-meshboard-settings-dialog", ngImport: i0, template: "<div class=\"meshboard-settings-dialog\">\n <kendo-tabstrip [animate]=\"false\">\n <!-- General Tab -->\n <kendo-tabstrip-tab [title]=\"'General'\" [selected]=\"true\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <form class=\"settings-form\">\n <!-- Name Field -->\n <kendo-formfield>\n <kendo-label [for]=\"nameInput\" text=\"Name *\"></kendo-label>\n <kendo-textbox\n #nameInput\n [(ngModel)]=\"name\"\n name=\"name\"\n placeholder=\"Enter MeshBoard name\"\n required>\n </kendo-textbox>\n @if (name.trim().length === 0) {\n <kendo-formerror>Name is required</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Description Field -->\n <kendo-formfield>\n <kendo-label [for]=\"descriptionInput\" text=\"Description\"></kendo-label>\n <kendo-textarea\n #descriptionInput\n [(ngModel)]=\"description\"\n name=\"description\"\n placeholder=\"Enter MeshBoard description (optional)\"\n [rows]=\"3\">\n </kendo-textarea>\n </kendo-formfield>\n\n <!-- Well-Known Name Field -->\n <kendo-formfield>\n <kendo-label [for]=\"wellKnownNameInput\" text=\"Well-Known Name\"></kendo-label>\n <kendo-textbox\n #wellKnownNameInput\n [(ngModel)]=\"rtWellKnownName\"\n name=\"rtWellKnownName\"\n placeholder=\"e.g., cockpit, dashboard-main\">\n </kendo-textbox>\n <kendo-formhint>Unique identifier for routing. Use lowercase with hyphens (e.g., 'cockpit', 'sales-dashboard').</kendo-formhint>\n </kendo-formfield>\n\n <!-- Layout Settings -->\n <div class=\"section-title\">Layout Settings</div>\n\n <!-- Columns Field -->\n <kendo-formfield>\n <kendo-label [for]=\"columnsInput\" text=\"Columns *\"></kendo-label>\n <kendo-numerictextbox\n #columnsInput\n [(ngModel)]=\"columns\"\n name=\"columns\"\n [min]=\"1\"\n [max]=\"12\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Number of columns in the grid (1-12)</kendo-formhint>\n @if (columns < 1 || columns > 12) {\n <kendo-formerror>Columns must be between 1 and 12</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Row Height Field -->\n <kendo-formfield>\n <kendo-label [for]=\"rowHeightInput\" text=\"Row Height *\"></kendo-label>\n <kendo-numerictextbox\n #rowHeightInput\n [(ngModel)]=\"rowHeight\"\n name=\"rowHeight\"\n [min]=\"100\"\n [max]=\"1000\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Height of each row in pixels (100-1000)</kendo-formhint>\n @if (rowHeight < 100 || rowHeight > 1000) {\n <kendo-formerror>Row height must be between 100 and 1000</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Gap Field -->\n <kendo-formfield>\n <kendo-label [for]=\"gapInput\" text=\"Gap *\"></kendo-label>\n <kendo-numerictextbox\n #gapInput\n [(ngModel)]=\"gap\"\n name=\"gap\"\n [min]=\"0\"\n [max]=\"100\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Space between widgets in pixels (0-100)</kendo-formhint>\n @if (gap < 0 || gap > 100) {\n <kendo-formerror>Gap must be between 0 and 100</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Auto-Refresh Field -->\n <kendo-formfield>\n <kendo-label [for]=\"autoRefreshInput\" text=\"Auto-refresh\"></kendo-label>\n <kendo-numerictextbox\n #autoRefreshInput\n [(ngModel)]=\"autoRefreshSeconds\"\n name=\"autoRefreshSeconds\"\n [min]=\"0\"\n [max]=\"3600\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\">\n </kendo-numerictextbox>\n <kendo-formhint>Refresh interval in seconds (0 = disabled, max 3600). Pauses while the tab is hidden.</kendo-formhint>\n @if (autoRefreshSeconds < 0 || autoRefreshSeconds > 3600) {\n <kendo-formerror>Auto-refresh must be between 0 and 3600 seconds</kendo-formerror>\n }\n </kendo-formfield>\n </form>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Variables Tab -->\n <kendo-tabstrip-tab [title]=\"'Variables'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <mm-variables-editor\n [(variables)]=\"variables\">\n </mm-variables-editor>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Time Filter Tab -->\n <kendo-tabstrip-tab [title]=\"'Time Filter'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <form class=\"settings-form\">\n <kendo-formfield>\n <kendo-label text=\"Timezone\"></kendo-label>\n <div class=\"radio-group\">\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzLocal\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n value=\"local\"\n id=\"timeZoneModeLocal\"/>\n <kendo-label [for]=\"tzLocal\" text=\"Local time (browser)\" class=\"radio-label\"></kendo-label>\n </div>\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzUtc\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n value=\"utc\"\n id=\"timeZoneModeUtc\"/>\n <kendo-label [for]=\"tzUtc\" text=\"UTC\" class=\"radio-label\"></kendo-label>\n </div>\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzZone\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n [value]=\"zoneSelection\"\n id=\"timeZoneModeZone\"/>\n <kendo-label [for]=\"tzZone\" text=\"Specific time zone\" class=\"radio-label\"></kendo-label>\n <kendo-dropdownlist\n class=\"tz-zone-select\"\n [data]=\"commonTimeZones\"\n [value]=\"zoneSelection\"\n (valueChange)=\"onZoneSelectionChange($event)\"\n [disabled]=\"!isSpecificZone\"\n [filterable]=\"true\"\n aria-label=\"IANA time zone\">\n </kendo-dropdownlist>\n </div>\n </div>\n <kendo-formhint>\n Basis for the time filter and for how all widgets display dates and times. Local time is the default.\n A specific time zone resolves civil days (today / yesterday / this month) DST-correctly in that\n zone and selects matching calendar rollups.\n </kendo-formhint>\n </kendo-formfield>\n\n <kendo-formfield>\n <div class=\"checkbox-wrapper\">\n <input\n type=\"checkbox\"\n kendoCheckBox\n #timeFilterCheckbox\n [(ngModel)]=\"timeFilterEnabled\"\n name=\"timeFilterEnabled\"\n id=\"timeFilterEnabled\"/>\n <kendo-label\n [for]=\"timeFilterCheckbox\"\n text=\"Enable Time Filter\"\n class=\"checkbox-label\">\n </kendo-label>\n </div>\n <kendo-formhint>\n Shows a time range picker in the toolbar. Sets $timeRangeFrom and $timeRangeTo variables.\n </kendo-formhint>\n </kendo-formfield>\n\n @if (timeFilterEnabled) {\n <kendo-formfield>\n <kendo-label text=\"Default Selection\"></kendo-label>\n <mm-time-range-picker\n [initialSelection]=\"initialDefaultSelection\"\n (selectionChange)=\"onDefaultSelectionChange($event)\">\n </mm-time-range-picker>\n <kendo-formhint>Initial time filter shown when no URL parameters are set. Note: User-selected filters override this default. Use the reset button in the toolbar to revert to the default.</kendo-formhint>\n </kendo-formfield>\n }\n </form>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Entity Selectors Tab -->\n <kendo-tabstrip-tab [title]=\"'Entity Selectors'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <mm-entity-selector-editor\n [(entitySelectors)]=\"entitySelectors\"\n [existingVariableNames]=\"staticVariableNames\"\n (editingStateChange)=\"entitySelectorEditing = $event\">\n </mm-entity-selector-editor>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n </kendo-tabstrip>\n\n <!-- Dialog Actions -->\n @if (!entitySelectorEditing) {\n <div class=\"dialog-actions mm-dialog-actions\">\n <button kendoButton (click)=\"cancel()\" fillMode=\"flat\">\n Cancel\n </button>\n <button\n kendoButton\n (click)=\"save()\"\n [disabled]=\"!isValid\"\n themeColor=\"primary\">\n Save\n </button>\n </div>\n }\n</div>\n", styles: [".meshboard-settings-dialog{display:flex;flex-direction:column;height:100%;overflow:hidden}.meshboard-settings-dialog kendo-tabstrip{flex:1;min-height:0;display:flex;flex-direction:column}.meshboard-settings-dialog kendo-tabstrip ::ng-deep .k-tabstrip-content{flex:1;min-height:0;overflow:hidden}.meshboard-settings-dialog .tab-content{height:100%;overflow-y:auto;padding:1.5rem}.meshboard-settings-dialog .settings-form{display:flex;flex-direction:column;gap:1.25rem}.meshboard-settings-dialog .settings-form kendo-formfield{display:flex;flex-direction:column;gap:.5rem}.meshboard-settings-dialog .settings-form kendo-formfield kendo-label{font-weight:500;color:var(--kendo-color-on-app-surface, #424242)}.meshboard-settings-dialog .settings-form kendo-formfield kendo-textbox,.meshboard-settings-dialog .settings-form kendo-formfield kendo-textarea,.meshboard-settings-dialog .settings-form kendo-formfield kendo-numerictextbox{width:100%}.meshboard-settings-dialog .settings-form kendo-formfield kendo-formhint{font-size:.75rem;color:var(--kendo-color-subtle, #757575)}.meshboard-settings-dialog .settings-form kendo-formfield kendo-formerror{font-size:.75rem;color:var(--kendo-color-error, #f44336)}.meshboard-settings-dialog .settings-form .section-title{font-size:.875rem;font-weight:600;color:var(--kendo-color-on-app-surface, #424242);text-transform:uppercase;letter-spacing:.5px;margin-top:.5rem;padding-bottom:.5rem;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.meshboard-settings-dialog .settings-form .checkbox-wrapper,.meshboard-settings-dialog .settings-form .radio-wrapper{display:flex;align-items:center;gap:.5rem}.meshboard-settings-dialog .settings-form .checkbox-wrapper .checkbox-label,.meshboard-settings-dialog .settings-form .checkbox-wrapper .radio-label,.meshboard-settings-dialog .settings-form .radio-wrapper .checkbox-label,.meshboard-settings-dialog .settings-form .radio-wrapper .radio-label{font-weight:400;cursor:pointer}.meshboard-settings-dialog .settings-form .checkbox-wrapper .tz-zone-select,.meshboard-settings-dialog .settings-form .radio-wrapper .tz-zone-select{min-width:12rem}.meshboard-settings-dialog .settings-form .radio-group{display:flex;flex-direction:column;gap:.5rem;margin-top:.25rem}.meshboard-settings-dialog .dialog-actions{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--kendo-color-border, #e0e0e0);flex-shrink:0;background-color:var(--kendo-color-surface-alt, white)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio]:not([ngNoCva])[formControlName],input[type=radio]:not([ngNoCva])[formControl],input[type=radio]:not([ngNoCva])[ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "component", type: i3.TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "directive", type: i3.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "directive", type: i3.RadioButtonDirective, selector: "input[kendoRadioButton]", inputs: ["size"] }, { kind: "component", type: i3.FormFieldComponent, selector: "kendo-formfield", inputs: ["showHints", "orientation", "showErrors", "colSpan"] }, { kind: "component", type: i3.HintComponent, selector: "kendo-formhint", inputs: ["align"] }, { kind: "component", type: i3.ErrorComponent, selector: "kendo-formerror", inputs: ["align"] }, { kind: "ngmodule", type: CheckBoxModule }, { kind: "ngmodule", type: LabelModule }, { kind: "component", type: i4$1.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "ngmodule", type: FormFieldModule }, { kind: "ngmodule", type: TabStripModule }, { kind: "component", type: i5.TabStripComponent, selector: "kendo-tabstrip", inputs: ["height", "animate", "tabAlignment", "tabPosition", "keepTabContent", "closable", "scrollable", "size", "closeIcon", "closeIconClass", "closeSVGIcon", "showContentArea"], outputs: ["tabSelect", "tabClose", "tabScroll"], exportAs: ["kendoTabStrip"] }, { kind: "component", type: i5.TabStripTabComponent, selector: "kendo-tabstrip-tab", inputs: ["title", "disabled", "cssClass", "cssStyle", "selected", "closable", "closeIcon", "closeIconClass", "closeSVGIcon"], exportAs: ["kendoTabStripTab"] }, { kind: "directive", type: i5.TabContentDirective, selector: "[kendoTabContent]" }, { kind: "ngmodule", type: DropDownListModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "component", type: VariablesEditorComponent, selector: "mm-variables-editor", inputs: ["variables"], outputs: ["variablesChange"] }, { kind: "component", type: EntitySelectorEditorComponent, selector: "mm-entity-selector-editor", inputs: ["entitySelectors", "existingVariableNames"], outputs: ["entitySelectorsChange", "editingStateChange"] }, { kind: "component", type: TimeRangePickerComponent, selector: "mm-time-range-picker", inputs: ["config", "labels", "initialSelection"], outputs: ["rangeChange", "rangeChangeISO", "selectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30471
31049
  }
30472
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardSettingsDialogComponent, decorators: [{
31050
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardSettingsDialogComponent, decorators: [{
30473
31051
  type: Component,
30474
31052
  args: [{ selector: 'mm-meshboard-settings-dialog', standalone: true, imports: [
30475
31053
  CommonModule,
@@ -30480,10 +31058,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
30480
31058
  LabelModule,
30481
31059
  FormFieldModule,
30482
31060
  TabStripModule,
31061
+ DropDownListModule,
30483
31062
  VariablesEditorComponent,
30484
31063
  EntitySelectorEditorComponent,
30485
31064
  TimeRangePickerComponent
30486
- ], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"meshboard-settings-dialog\">\n <kendo-tabstrip [animate]=\"false\">\n <!-- General Tab -->\n <kendo-tabstrip-tab [title]=\"'General'\" [selected]=\"true\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <form class=\"settings-form\">\n <!-- Name Field -->\n <kendo-formfield>\n <kendo-label [for]=\"nameInput\" text=\"Name *\"></kendo-label>\n <kendo-textbox\n #nameInput\n [(ngModel)]=\"name\"\n name=\"name\"\n placeholder=\"Enter MeshBoard name\"\n required>\n </kendo-textbox>\n @if (name.trim().length === 0) {\n <kendo-formerror>Name is required</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Description Field -->\n <kendo-formfield>\n <kendo-label [for]=\"descriptionInput\" text=\"Description\"></kendo-label>\n <kendo-textarea\n #descriptionInput\n [(ngModel)]=\"description\"\n name=\"description\"\n placeholder=\"Enter MeshBoard description (optional)\"\n [rows]=\"3\">\n </kendo-textarea>\n </kendo-formfield>\n\n <!-- Well-Known Name Field -->\n <kendo-formfield>\n <kendo-label [for]=\"wellKnownNameInput\" text=\"Well-Known Name\"></kendo-label>\n <kendo-textbox\n #wellKnownNameInput\n [(ngModel)]=\"rtWellKnownName\"\n name=\"rtWellKnownName\"\n placeholder=\"e.g., cockpit, dashboard-main\">\n </kendo-textbox>\n <kendo-formhint>Unique identifier for routing. Use lowercase with hyphens (e.g., 'cockpit', 'sales-dashboard').</kendo-formhint>\n </kendo-formfield>\n\n <!-- Layout Settings -->\n <div class=\"section-title\">Layout Settings</div>\n\n <!-- Columns Field -->\n <kendo-formfield>\n <kendo-label [for]=\"columnsInput\" text=\"Columns *\"></kendo-label>\n <kendo-numerictextbox\n #columnsInput\n [(ngModel)]=\"columns\"\n name=\"columns\"\n [min]=\"1\"\n [max]=\"12\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Number of columns in the grid (1-12)</kendo-formhint>\n @if (columns < 1 || columns > 12) {\n <kendo-formerror>Columns must be between 1 and 12</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Row Height Field -->\n <kendo-formfield>\n <kendo-label [for]=\"rowHeightInput\" text=\"Row Height *\"></kendo-label>\n <kendo-numerictextbox\n #rowHeightInput\n [(ngModel)]=\"rowHeight\"\n name=\"rowHeight\"\n [min]=\"100\"\n [max]=\"1000\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Height of each row in pixels (100-1000)</kendo-formhint>\n @if (rowHeight < 100 || rowHeight > 1000) {\n <kendo-formerror>Row height must be between 100 and 1000</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Gap Field -->\n <kendo-formfield>\n <kendo-label [for]=\"gapInput\" text=\"Gap *\"></kendo-label>\n <kendo-numerictextbox\n #gapInput\n [(ngModel)]=\"gap\"\n name=\"gap\"\n [min]=\"0\"\n [max]=\"100\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Space between widgets in pixels (0-100)</kendo-formhint>\n @if (gap < 0 || gap > 100) {\n <kendo-formerror>Gap must be between 0 and 100</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Auto-Refresh Field -->\n <kendo-formfield>\n <kendo-label [for]=\"autoRefreshInput\" text=\"Auto-refresh\"></kendo-label>\n <kendo-numerictextbox\n #autoRefreshInput\n [(ngModel)]=\"autoRefreshSeconds\"\n name=\"autoRefreshSeconds\"\n [min]=\"0\"\n [max]=\"3600\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\">\n </kendo-numerictextbox>\n <kendo-formhint>Refresh interval in seconds (0 = disabled, max 3600). Pauses while the tab is hidden.</kendo-formhint>\n @if (autoRefreshSeconds < 0 || autoRefreshSeconds > 3600) {\n <kendo-formerror>Auto-refresh must be between 0 and 3600 seconds</kendo-formerror>\n }\n </kendo-formfield>\n </form>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Variables Tab -->\n <kendo-tabstrip-tab [title]=\"'Variables'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <mm-variables-editor\n [(variables)]=\"variables\">\n </mm-variables-editor>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Time Filter Tab -->\n <kendo-tabstrip-tab [title]=\"'Time Filter'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <form class=\"settings-form\">\n <kendo-formfield>\n <kendo-label text=\"Timezone\"></kendo-label>\n <div class=\"radio-group\">\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzLocal\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n value=\"local\"\n id=\"timeZoneModeLocal\"/>\n <kendo-label [for]=\"tzLocal\" text=\"Local time (browser)\" class=\"radio-label\"></kendo-label>\n </div>\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzUtc\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n value=\"utc\"\n id=\"timeZoneModeUtc\"/>\n <kendo-label [for]=\"tzUtc\" text=\"UTC\" class=\"radio-label\"></kendo-label>\n </div>\n </div>\n <kendo-formhint>\n Basis for the time filter and for how all widgets display dates and times. Local time is the default.\n </kendo-formhint>\n </kendo-formfield>\n\n <kendo-formfield>\n <div class=\"checkbox-wrapper\">\n <input\n type=\"checkbox\"\n kendoCheckBox\n #timeFilterCheckbox\n [(ngModel)]=\"timeFilterEnabled\"\n name=\"timeFilterEnabled\"\n id=\"timeFilterEnabled\"/>\n <kendo-label\n [for]=\"timeFilterCheckbox\"\n text=\"Enable Time Filter\"\n class=\"checkbox-label\">\n </kendo-label>\n </div>\n <kendo-formhint>\n Shows a time range picker in the toolbar. Sets $timeRangeFrom and $timeRangeTo variables.\n </kendo-formhint>\n </kendo-formfield>\n\n @if (timeFilterEnabled) {\n <kendo-formfield>\n <kendo-label text=\"Default Selection\"></kendo-label>\n <mm-time-range-picker\n [initialSelection]=\"initialDefaultSelection\"\n (selectionChange)=\"onDefaultSelectionChange($event)\">\n </mm-time-range-picker>\n <kendo-formhint>Initial time filter shown when no URL parameters are set. Note: User-selected filters override this default. Use the reset button in the toolbar to revert to the default.</kendo-formhint>\n </kendo-formfield>\n }\n </form>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Entity Selectors Tab -->\n <kendo-tabstrip-tab [title]=\"'Entity Selectors'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <mm-entity-selector-editor\n [(entitySelectors)]=\"entitySelectors\"\n [existingVariableNames]=\"staticVariableNames\"\n (editingStateChange)=\"entitySelectorEditing = $event\">\n </mm-entity-selector-editor>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n </kendo-tabstrip>\n\n <!-- Dialog Actions -->\n @if (!entitySelectorEditing) {\n <div class=\"dialog-actions mm-dialog-actions\">\n <button kendoButton (click)=\"cancel()\" fillMode=\"flat\">\n Cancel\n </button>\n <button\n kendoButton\n (click)=\"save()\"\n [disabled]=\"!isValid\"\n themeColor=\"primary\">\n Save\n </button>\n </div>\n }\n</div>\n", styles: [".meshboard-settings-dialog{display:flex;flex-direction:column;height:100%;overflow:hidden}.meshboard-settings-dialog kendo-tabstrip{flex:1;min-height:0;display:flex;flex-direction:column}.meshboard-settings-dialog kendo-tabstrip ::ng-deep .k-tabstrip-content{flex:1;min-height:0;overflow:hidden}.meshboard-settings-dialog .tab-content{height:100%;overflow-y:auto;padding:1.5rem}.meshboard-settings-dialog .settings-form{display:flex;flex-direction:column;gap:1.25rem}.meshboard-settings-dialog .settings-form kendo-formfield{display:flex;flex-direction:column;gap:.5rem}.meshboard-settings-dialog .settings-form kendo-formfield kendo-label{font-weight:500;color:var(--kendo-color-on-app-surface, #424242)}.meshboard-settings-dialog .settings-form kendo-formfield kendo-textbox,.meshboard-settings-dialog .settings-form kendo-formfield kendo-textarea,.meshboard-settings-dialog .settings-form kendo-formfield kendo-numerictextbox{width:100%}.meshboard-settings-dialog .settings-form kendo-formfield kendo-formhint{font-size:.75rem;color:var(--kendo-color-subtle, #757575)}.meshboard-settings-dialog .settings-form kendo-formfield kendo-formerror{font-size:.75rem;color:var(--kendo-color-error, #f44336)}.meshboard-settings-dialog .settings-form .section-title{font-size:.875rem;font-weight:600;color:var(--kendo-color-on-app-surface, #424242);text-transform:uppercase;letter-spacing:.5px;margin-top:.5rem;padding-bottom:.5rem;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.meshboard-settings-dialog .settings-form .checkbox-wrapper,.meshboard-settings-dialog .settings-form .radio-wrapper{display:flex;align-items:center;gap:.5rem}.meshboard-settings-dialog .settings-form .checkbox-wrapper .checkbox-label,.meshboard-settings-dialog .settings-form .checkbox-wrapper .radio-label,.meshboard-settings-dialog .settings-form .radio-wrapper .checkbox-label,.meshboard-settings-dialog .settings-form .radio-wrapper .radio-label{font-weight:400;cursor:pointer}.meshboard-settings-dialog .settings-form .radio-group{display:flex;flex-direction:column;gap:.5rem;margin-top:.25rem}.meshboard-settings-dialog .dialog-actions{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--kendo-color-border, #e0e0e0);flex-shrink:0;background-color:var(--kendo-color-surface-alt, white)}\n"] }]
31065
+ ], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"meshboard-settings-dialog\">\n <kendo-tabstrip [animate]=\"false\">\n <!-- General Tab -->\n <kendo-tabstrip-tab [title]=\"'General'\" [selected]=\"true\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <form class=\"settings-form\">\n <!-- Name Field -->\n <kendo-formfield>\n <kendo-label [for]=\"nameInput\" text=\"Name *\"></kendo-label>\n <kendo-textbox\n #nameInput\n [(ngModel)]=\"name\"\n name=\"name\"\n placeholder=\"Enter MeshBoard name\"\n required>\n </kendo-textbox>\n @if (name.trim().length === 0) {\n <kendo-formerror>Name is required</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Description Field -->\n <kendo-formfield>\n <kendo-label [for]=\"descriptionInput\" text=\"Description\"></kendo-label>\n <kendo-textarea\n #descriptionInput\n [(ngModel)]=\"description\"\n name=\"description\"\n placeholder=\"Enter MeshBoard description (optional)\"\n [rows]=\"3\">\n </kendo-textarea>\n </kendo-formfield>\n\n <!-- Well-Known Name Field -->\n <kendo-formfield>\n <kendo-label [for]=\"wellKnownNameInput\" text=\"Well-Known Name\"></kendo-label>\n <kendo-textbox\n #wellKnownNameInput\n [(ngModel)]=\"rtWellKnownName\"\n name=\"rtWellKnownName\"\n placeholder=\"e.g., cockpit, dashboard-main\">\n </kendo-textbox>\n <kendo-formhint>Unique identifier for routing. Use lowercase with hyphens (e.g., 'cockpit', 'sales-dashboard').</kendo-formhint>\n </kendo-formfield>\n\n <!-- Layout Settings -->\n <div class=\"section-title\">Layout Settings</div>\n\n <!-- Columns Field -->\n <kendo-formfield>\n <kendo-label [for]=\"columnsInput\" text=\"Columns *\"></kendo-label>\n <kendo-numerictextbox\n #columnsInput\n [(ngModel)]=\"columns\"\n name=\"columns\"\n [min]=\"1\"\n [max]=\"12\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Number of columns in the grid (1-12)</kendo-formhint>\n @if (columns < 1 || columns > 12) {\n <kendo-formerror>Columns must be between 1 and 12</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Row Height Field -->\n <kendo-formfield>\n <kendo-label [for]=\"rowHeightInput\" text=\"Row Height *\"></kendo-label>\n <kendo-numerictextbox\n #rowHeightInput\n [(ngModel)]=\"rowHeight\"\n name=\"rowHeight\"\n [min]=\"100\"\n [max]=\"1000\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Height of each row in pixels (100-1000)</kendo-formhint>\n @if (rowHeight < 100 || rowHeight > 1000) {\n <kendo-formerror>Row height must be between 100 and 1000</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Gap Field -->\n <kendo-formfield>\n <kendo-label [for]=\"gapInput\" text=\"Gap *\"></kendo-label>\n <kendo-numerictextbox\n #gapInput\n [(ngModel)]=\"gap\"\n name=\"gap\"\n [min]=\"0\"\n [max]=\"100\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\"\n required>\n </kendo-numerictextbox>\n <kendo-formhint>Space between widgets in pixels (0-100)</kendo-formhint>\n @if (gap < 0 || gap > 100) {\n <kendo-formerror>Gap must be between 0 and 100</kendo-formerror>\n }\n </kendo-formfield>\n\n <!-- Auto-Refresh Field -->\n <kendo-formfield>\n <kendo-label [for]=\"autoRefreshInput\" text=\"Auto-refresh\"></kendo-label>\n <kendo-numerictextbox\n #autoRefreshInput\n [(ngModel)]=\"autoRefreshSeconds\"\n name=\"autoRefreshSeconds\"\n [min]=\"0\"\n [max]=\"3600\"\n [decimals]=\"0\"\n [format]=\"'n0'\"\n [spinners]=\"true\">\n </kendo-numerictextbox>\n <kendo-formhint>Refresh interval in seconds (0 = disabled, max 3600). Pauses while the tab is hidden.</kendo-formhint>\n @if (autoRefreshSeconds < 0 || autoRefreshSeconds > 3600) {\n <kendo-formerror>Auto-refresh must be between 0 and 3600 seconds</kendo-formerror>\n }\n </kendo-formfield>\n </form>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Variables Tab -->\n <kendo-tabstrip-tab [title]=\"'Variables'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <mm-variables-editor\n [(variables)]=\"variables\">\n </mm-variables-editor>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Time Filter Tab -->\n <kendo-tabstrip-tab [title]=\"'Time Filter'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <form class=\"settings-form\">\n <kendo-formfield>\n <kendo-label text=\"Timezone\"></kendo-label>\n <div class=\"radio-group\">\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzLocal\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n value=\"local\"\n id=\"timeZoneModeLocal\"/>\n <kendo-label [for]=\"tzLocal\" text=\"Local time (browser)\" class=\"radio-label\"></kendo-label>\n </div>\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzUtc\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n value=\"utc\"\n id=\"timeZoneModeUtc\"/>\n <kendo-label [for]=\"tzUtc\" text=\"UTC\" class=\"radio-label\"></kendo-label>\n </div>\n <div class=\"radio-wrapper\">\n <input\n type=\"radio\"\n kendoRadioButton\n #tzZone\n [(ngModel)]=\"timeZoneMode\"\n name=\"timeZoneMode\"\n [value]=\"zoneSelection\"\n id=\"timeZoneModeZone\"/>\n <kendo-label [for]=\"tzZone\" text=\"Specific time zone\" class=\"radio-label\"></kendo-label>\n <kendo-dropdownlist\n class=\"tz-zone-select\"\n [data]=\"commonTimeZones\"\n [value]=\"zoneSelection\"\n (valueChange)=\"onZoneSelectionChange($event)\"\n [disabled]=\"!isSpecificZone\"\n [filterable]=\"true\"\n aria-label=\"IANA time zone\">\n </kendo-dropdownlist>\n </div>\n </div>\n <kendo-formhint>\n Basis for the time filter and for how all widgets display dates and times. Local time is the default.\n A specific time zone resolves civil days (today / yesterday / this month) DST-correctly in that\n zone and selects matching calendar rollups.\n </kendo-formhint>\n </kendo-formfield>\n\n <kendo-formfield>\n <div class=\"checkbox-wrapper\">\n <input\n type=\"checkbox\"\n kendoCheckBox\n #timeFilterCheckbox\n [(ngModel)]=\"timeFilterEnabled\"\n name=\"timeFilterEnabled\"\n id=\"timeFilterEnabled\"/>\n <kendo-label\n [for]=\"timeFilterCheckbox\"\n text=\"Enable Time Filter\"\n class=\"checkbox-label\">\n </kendo-label>\n </div>\n <kendo-formhint>\n Shows a time range picker in the toolbar. Sets $timeRangeFrom and $timeRangeTo variables.\n </kendo-formhint>\n </kendo-formfield>\n\n @if (timeFilterEnabled) {\n <kendo-formfield>\n <kendo-label text=\"Default Selection\"></kendo-label>\n <mm-time-range-picker\n [initialSelection]=\"initialDefaultSelection\"\n (selectionChange)=\"onDefaultSelectionChange($event)\">\n </mm-time-range-picker>\n <kendo-formhint>Initial time filter shown when no URL parameters are set. Note: User-selected filters override this default. Use the reset button in the toolbar to revert to the default.</kendo-formhint>\n </kendo-formfield>\n }\n </form>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n\n <!-- Entity Selectors Tab -->\n <kendo-tabstrip-tab [title]=\"'Entity Selectors'\">\n <ng-template kendoTabContent>\n <div class=\"tab-content\">\n <mm-entity-selector-editor\n [(entitySelectors)]=\"entitySelectors\"\n [existingVariableNames]=\"staticVariableNames\"\n (editingStateChange)=\"entitySelectorEditing = $event\">\n </mm-entity-selector-editor>\n </div>\n </ng-template>\n </kendo-tabstrip-tab>\n </kendo-tabstrip>\n\n <!-- Dialog Actions -->\n @if (!entitySelectorEditing) {\n <div class=\"dialog-actions mm-dialog-actions\">\n <button kendoButton (click)=\"cancel()\" fillMode=\"flat\">\n Cancel\n </button>\n <button\n kendoButton\n (click)=\"save()\"\n [disabled]=\"!isValid\"\n themeColor=\"primary\">\n Save\n </button>\n </div>\n }\n</div>\n", styles: [".meshboard-settings-dialog{display:flex;flex-direction:column;height:100%;overflow:hidden}.meshboard-settings-dialog kendo-tabstrip{flex:1;min-height:0;display:flex;flex-direction:column}.meshboard-settings-dialog kendo-tabstrip ::ng-deep .k-tabstrip-content{flex:1;min-height:0;overflow:hidden}.meshboard-settings-dialog .tab-content{height:100%;overflow-y:auto;padding:1.5rem}.meshboard-settings-dialog .settings-form{display:flex;flex-direction:column;gap:1.25rem}.meshboard-settings-dialog .settings-form kendo-formfield{display:flex;flex-direction:column;gap:.5rem}.meshboard-settings-dialog .settings-form kendo-formfield kendo-label{font-weight:500;color:var(--kendo-color-on-app-surface, #424242)}.meshboard-settings-dialog .settings-form kendo-formfield kendo-textbox,.meshboard-settings-dialog .settings-form kendo-formfield kendo-textarea,.meshboard-settings-dialog .settings-form kendo-formfield kendo-numerictextbox{width:100%}.meshboard-settings-dialog .settings-form kendo-formfield kendo-formhint{font-size:.75rem;color:var(--kendo-color-subtle, #757575)}.meshboard-settings-dialog .settings-form kendo-formfield kendo-formerror{font-size:.75rem;color:var(--kendo-color-error, #f44336)}.meshboard-settings-dialog .settings-form .section-title{font-size:.875rem;font-weight:600;color:var(--kendo-color-on-app-surface, #424242);text-transform:uppercase;letter-spacing:.5px;margin-top:.5rem;padding-bottom:.5rem;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.meshboard-settings-dialog .settings-form .checkbox-wrapper,.meshboard-settings-dialog .settings-form .radio-wrapper{display:flex;align-items:center;gap:.5rem}.meshboard-settings-dialog .settings-form .checkbox-wrapper .checkbox-label,.meshboard-settings-dialog .settings-form .checkbox-wrapper .radio-label,.meshboard-settings-dialog .settings-form .radio-wrapper .checkbox-label,.meshboard-settings-dialog .settings-form .radio-wrapper .radio-label{font-weight:400;cursor:pointer}.meshboard-settings-dialog .settings-form .checkbox-wrapper .tz-zone-select,.meshboard-settings-dialog .settings-form .radio-wrapper .tz-zone-select{min-width:12rem}.meshboard-settings-dialog .settings-form .radio-group{display:flex;flex-direction:column;gap:.5rem;margin-top:.25rem}.meshboard-settings-dialog .dialog-actions{display:flex;justify-content:flex-end;gap:.75rem;padding:1rem 1.5rem;border-top:1px solid var(--kendo-color-border, #e0e0e0);flex-shrink:0;background-color:var(--kendo-color-surface-alt, white)}\n"] }]
30487
31066
  }] });
30488
31067
 
30489
31068
  /**
@@ -30615,10 +31194,10 @@ class AddWidgetDialogComponent {
30615
31194
  cancel() {
30616
31195
  this.dialogRef.close();
30617
31196
  }
30618
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AddWidgetDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30619
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: AddWidgetDialogComponent, isStandalone: true, selector: "mm-add-widget-dialog", ngImport: i0, template: "<div class=\"add-widget-dialog\">\n <div class=\"dialog-content\">\n <p class=\"dialog-description\">\n Select a widget type to add to your MeshBoard:\n </p>\n\n <div class=\"widget-types-list\">\n <div class=\"list-header\">Available Widgets</div>\n\n @for (item of widgetTypes(); track item.type) {\n <div\n class=\"widget-type-item\"\n [class.selected]=\"isSelected(item.type)\"\n (click)=\"selectType(item.type)\">\n <div class=\"widget-icon\">\n <kendo-svg-icon [icon]=\"item.icon\" size=\"large\"></kendo-svg-icon>\n </div>\n <div class=\"widget-info\">\n <h4 class=\"widget-label\">{{ item.label }}</h4>\n <p class=\"widget-description\">{{ item.description }}</p>\n </div>\n @if (isSelected(item.type)) {\n <div class=\"selected-indicator\">\n <kendo-svg-icon [icon]=\"checkCircleIcon\" size=\"medium\"></kendo-svg-icon>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Dialog Actions -->\n <div class=\"dialog-actions mm-dialog-actions\">\n <button kendoButton (click)=\"cancel()\" fillMode=\"flat\">\n Cancel\n </button>\n <button\n kendoButton\n (click)=\"add()\"\n [disabled]=\"!selectedType()\"\n themeColor=\"primary\">\n Add Widget\n </button>\n </div>\n</div>\n", styles: [".add-widget-dialog{display:flex;flex-direction:column;gap:.75rem;padding:.75rem;max-height:60vh;overflow:hidden}.add-widget-dialog .dialog-content{display:flex;flex-direction:column;gap:1rem;flex:1;min-height:0;overflow:hidden}.add-widget-dialog .dialog-content .dialog-description{margin:0;color:var(--kendo-color-subtle, #757575);font-size:.875rem}.add-widget-dialog .dialog-content .widget-types-list{flex:1;overflow-y:auto;border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px}.add-widget-dialog .dialog-content .widget-types-list .list-header{font-weight:600;font-size:.75rem;color:var(--kendo-color-on-app-surface, #424242);padding:.5rem .75rem;background-color:var(--kendo-color-surface-alt, #fafafa);border-bottom:1px solid var(--kendo-color-border, #e0e0e0);text-transform:uppercase;letter-spacing:.5px}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item{display:flex;align-items:center;gap:.5rem;padding:.375rem .5rem;cursor:pointer;border-bottom:1px solid var(--kendo-color-border, #e0e0e0);transition:background-color .2s,box-shadow .2s}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item:last-child{border-bottom:none}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item:hover{background-color:var(--kendo-color-base-hover, #f5f5f5)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item.selected{background-color:var(--kendo-color-primary-subtle, #e8eaf6);box-shadow:inset 3px 0 0 var(--kendo-color-primary, #3f51b5)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:4px;background-color:var(--kendo-color-surface-alt, #f5f5f5);color:var(--kendo-color-primary, #3f51b5)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-icon kendo-svg-icon{color:inherit}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-info{flex:1;min-width:0}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-info .widget-label{margin:0 0 .125rem;font-size:.875rem;font-weight:500;color:var(--kendo-color-on-app-surface, #212121)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-info .widget-description{margin:0;font-size:.75rem;color:var(--kendo-color-subtle, #757575);line-height:1.3}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .selected-indicator{flex-shrink:0;color:var(--kendo-color-primary, #3f51b5)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .selected-indicator kendo-svg-icon{color:inherit}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item.selected .widget-icon{background-color:var(--kendo-color-primary, #3f51b5);color:var(--kendo-color-on-primary, #ffffff)}.add-widget-dialog .dialog-actions{display:flex;justify-content:flex-end;gap:.5rem;padding-top:.5rem;border-top:1px solid var(--kendo-color-border, #e0e0e0);flex-shrink:0}.widget-types-list::-webkit-scrollbar{width:8px}.widget-types-list::-webkit-scrollbar-track{background:var(--kendo-color-surface-alt, #f5f5f5)}.widget-types-list::-webkit-scrollbar-thumb{background:var(--kendo-color-border, #e0e0e0);border-radius:4px}.widget-types-list::-webkit-scrollbar-thumb:hover{background:var(--kendo-color-subtle, #9e9e9e)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
31197
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AddWidgetDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31198
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: AddWidgetDialogComponent, isStandalone: true, selector: "mm-add-widget-dialog", ngImport: i0, template: "<div class=\"add-widget-dialog\">\n <div class=\"dialog-content\">\n <p class=\"dialog-description\">\n Select a widget type to add to your MeshBoard:\n </p>\n\n <div class=\"widget-types-list\">\n <div class=\"list-header\">Available Widgets</div>\n\n @for (item of widgetTypes(); track item.type) {\n <div\n class=\"widget-type-item\"\n [class.selected]=\"isSelected(item.type)\"\n (click)=\"selectType(item.type)\">\n <div class=\"widget-icon\">\n <kendo-svg-icon [icon]=\"item.icon\" size=\"large\"></kendo-svg-icon>\n </div>\n <div class=\"widget-info\">\n <h4 class=\"widget-label\">{{ item.label }}</h4>\n <p class=\"widget-description\">{{ item.description }}</p>\n </div>\n @if (isSelected(item.type)) {\n <div class=\"selected-indicator\">\n <kendo-svg-icon [icon]=\"checkCircleIcon\" size=\"medium\"></kendo-svg-icon>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Dialog Actions -->\n <div class=\"dialog-actions mm-dialog-actions\">\n <button kendoButton (click)=\"cancel()\" fillMode=\"flat\">\n Cancel\n </button>\n <button\n kendoButton\n (click)=\"add()\"\n [disabled]=\"!selectedType()\"\n themeColor=\"primary\">\n Add Widget\n </button>\n </div>\n</div>\n", styles: [".add-widget-dialog{display:flex;flex-direction:column;gap:.75rem;padding:.75rem;max-height:60vh;overflow:hidden}.add-widget-dialog .dialog-content{display:flex;flex-direction:column;gap:1rem;flex:1;min-height:0;overflow:hidden}.add-widget-dialog .dialog-content .dialog-description{margin:0;color:var(--kendo-color-subtle, #757575);font-size:.875rem}.add-widget-dialog .dialog-content .widget-types-list{flex:1;overflow-y:auto;border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px}.add-widget-dialog .dialog-content .widget-types-list .list-header{font-weight:600;font-size:.75rem;color:var(--kendo-color-on-app-surface, #424242);padding:.5rem .75rem;background-color:var(--kendo-color-surface-alt, #fafafa);border-bottom:1px solid var(--kendo-color-border, #e0e0e0);text-transform:uppercase;letter-spacing:.5px}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item{display:flex;align-items:center;gap:.5rem;padding:.375rem .5rem;cursor:pointer;border-bottom:1px solid var(--kendo-color-border, #e0e0e0);transition:background-color .2s,box-shadow .2s}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item:last-child{border-bottom:none}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item:hover{background-color:var(--kendo-color-base-hover, #f5f5f5)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item.selected{background-color:var(--kendo-color-primary-subtle, #e8eaf6);box-shadow:inset 3px 0 0 var(--kendo-color-primary, #3f51b5)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:4px;background-color:var(--kendo-color-surface-alt, #f5f5f5);color:var(--kendo-color-primary, #3f51b5)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-icon kendo-svg-icon{color:inherit}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-info{flex:1;min-width:0}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-info .widget-label{margin:0 0 .125rem;font-size:.875rem;font-weight:500;color:var(--kendo-color-on-app-surface, #212121)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .widget-info .widget-description{margin:0;font-size:.75rem;color:var(--kendo-color-subtle, #757575);line-height:1.3}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .selected-indicator{flex-shrink:0;color:var(--kendo-color-primary, #3f51b5)}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item .selected-indicator kendo-svg-icon{color:inherit}.add-widget-dialog .dialog-content .widget-types-list .widget-type-item.selected .widget-icon{background-color:var(--kendo-color-primary, #3f51b5);color:var(--kendo-color-on-primary, #ffffff)}.add-widget-dialog .dialog-actions{display:flex;justify-content:flex-end;gap:.5rem;padding-top:.5rem;border-top:1px solid var(--kendo-color-border, #e0e0e0);flex-shrink:0}.widget-types-list::-webkit-scrollbar{width:8px}.widget-types-list::-webkit-scrollbar-track{background:var(--kendo-color-surface-alt, #f5f5f5)}.widget-types-list::-webkit-scrollbar-thumb{background:var(--kendo-color-border, #e0e0e0);border-radius:4px}.widget-types-list::-webkit-scrollbar-thumb:hover{background:var(--kendo-color-subtle, #9e9e9e)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30620
31199
  }
30621
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: AddWidgetDialogComponent, decorators: [{
31200
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: AddWidgetDialogComponent, decorators: [{
30622
31201
  type: Component,
30623
31202
  args: [{ selector: 'mm-add-widget-dialog', standalone: true, imports: [
30624
31203
  CommonModule,
@@ -31008,10 +31587,10 @@ class MeshBoardManagerDialogComponent {
31008
31587
  this.isImporting.set(false);
31009
31588
  }
31010
31589
  }
31011
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardManagerDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31012
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: MeshBoardManagerDialogComponent, isStandalone: true, selector: "mm-meshboard-manager-dialog", ngImport: i0, template: "<div class=\"meshboard-manager-dialog\">\n <!-- Header with Create/Import Buttons -->\n <div class=\"dialog-header\">\n <p class=\"dialog-description\">Manage your MeshBoards</p>\n <div class=\"header-actions\">\n @if (canExport) {\n <button\n kendoButton\n [svgIcon]=\"uploadIcon\"\n (click)=\"triggerImport()\"\n [disabled]=\"isCreating() || isLoading() || isImporting()\"\n fillMode=\"outline\">\n Import\n </button>\n }\n <button\n kendoButton\n [svgIcon]=\"plusIcon\"\n (click)=\"startCreate()\"\n [disabled]=\"isCreating() || isLoading()\"\n themeColor=\"primary\">\n New MeshBoard\n </button>\n </div>\n </div>\n\n <!-- Create New MeshBoard Form -->\n @if (isCreating()) {\n <div class=\"create-form\">\n <h4 class=\"form-title\">Create New MeshBoard</h4>\n <div class=\"form-fields\">\n <kendo-textbox\n [(ngModel)]=\"newName\"\n placeholder=\"MeshBoard name\"\n [disabled]=\"isLoading()\">\n </kendo-textbox>\n <kendo-textarea\n [(ngModel)]=\"newDescription\"\n placeholder=\"Description (optional)\"\n [rows]=\"2\"\n [disabled]=\"isLoading()\">\n </kendo-textarea>\n </div>\n <div class=\"form-actions\">\n <button\n kendoButton\n [svgIcon]=\"xIcon\"\n (click)=\"cancelCreate()\"\n [disabled]=\"isLoading()\"\n fillMode=\"flat\"\n size=\"small\">\n Cancel\n </button>\n <button\n kendoButton\n [svgIcon]=\"checkIcon\"\n (click)=\"create()\"\n [disabled]=\"newName().trim().length === 0 || isLoading()\"\n themeColor=\"primary\"\n size=\"small\">\n Create\n </button>\n </div>\n </div>\n }\n\n <!-- MeshBoards List -->\n <div class=\"meshboards-list\">\n @if (isLoading()) {\n <div class=\"loading-state\">\n <span class=\"k-loading-text\">Loading...</span>\n </div>\n } @else if (hasMeshBoards()) {\n @for (item of meshBoards(); track item.rtId) {\n <div\n class=\"meshboard-item\"\n [class.active]=\"isActive(item)\"\n [class.editing]=\"isEditing(item)\">\n\n @if (!isEditing(item)) {\n <!-- Display Mode -->\n <div class=\"item-content\" (click)=\"switchTo(item)\">\n <div class=\"item-icon\">\n <kendo-svg-icon [icon]=\"gridLayoutIcon\" size=\"large\"></kendo-svg-icon>\n </div>\n <div class=\"item-info\">\n <h4 class=\"item-name\">\n {{ item.name }}\n @if (isActive(item)) {\n <span class=\"active-badge\">Active</span>\n }\n </h4>\n @if (getDisplayDescription(item)) {\n <p class=\"item-description\">{{ getDisplayDescription(item) }}</p>\n }\n </div>\n <div class=\"item-actions\">\n @if (canExport) {\n <button\n kendoButton\n [svgIcon]=\"downloadIcon\"\n (click)=\"exportMeshBoard(item, $event)\"\n [disabled]=\"isLoading() || isExporting()\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Export\">\n </button>\n }\n <button\n kendoButton\n [svgIcon]=\"copyIcon\"\n (click)=\"duplicate(item); $event.stopPropagation()\"\n [disabled]=\"isLoading() || isDuplicating()\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Duplicate\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"pencilIcon\"\n (click)=\"startEdit(item); $event.stopPropagation()\"\n [disabled]=\"isLoading()\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Edit\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"trashIcon\"\n (click)=\"delete(item); $event.stopPropagation()\"\n [disabled]=\"isLoading()\"\n fillMode=\"flat\"\n size=\"small\"\n themeColor=\"error\"\n title=\"Delete\">\n </button>\n </div>\n </div>\n } @else {\n <!-- Edit Mode -->\n <div class=\"item-edit\">\n <div class=\"edit-fields\">\n <kendo-textbox\n [(ngModel)]=\"editingName\"\n placeholder=\"MeshBoard name\"\n [disabled]=\"isLoading()\">\n </kendo-textbox>\n <kendo-textarea\n [(ngModel)]=\"editingDescription\"\n placeholder=\"Description (optional)\"\n [rows]=\"2\"\n [disabled]=\"isLoading()\">\n </kendo-textarea>\n </div>\n <div class=\"edit-actions mm-dialog-actions\">\n <button\n kendoButton\n [svgIcon]=\"xIcon\"\n (click)=\"cancelEdit()\"\n [disabled]=\"isLoading()\"\n fillMode=\"flat\"\n size=\"small\">\n Cancel\n </button>\n <button\n kendoButton\n [svgIcon]=\"checkIcon\"\n (click)=\"saveEdit()\"\n [disabled]=\"editingName().trim().length === 0 || isLoading()\"\n themeColor=\"primary\"\n size=\"small\">\n Save\n </button>\n </div>\n </div>\n }\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <kendo-svg-icon [icon]=\"gridLayoutIcon\" size=\"xlarge\"></kendo-svg-icon>\n <h3>No MeshBoards</h3>\n <p>Create your first MeshBoard to get started.</p>\n </div>\n }\n </div>\n\n <!-- Dialog Actions -->\n <div class=\"dialog-actions mm-dialog-actions\">\n <button kendoButton (click)=\"close()\" fillMode=\"flat\">\n Close\n </button>\n </div>\n</div>\n", styles: [".meshboard-manager-dialog{display:flex;flex-direction:column;gap:.75rem;padding:.75rem .75rem 1.5rem;overflow:hidden}.meshboard-manager-dialog .dialog-header{display:flex;justify-content:space-between;align-items:center;gap:1rem}.meshboard-manager-dialog .dialog-header .dialog-description{margin:0;color:var(--kendo-color-subtle, #757575);font-size:.875rem;flex:1}.meshboard-manager-dialog .dialog-header .header-actions{display:flex;gap:.5rem}.meshboard-manager-dialog .create-form{padding:1rem;background-color:var(--kendo-color-surface-alt, #fafafa);border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px}.meshboard-manager-dialog .create-form .form-title{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--kendo-color-on-app-surface, #424242)}.meshboard-manager-dialog .create-form .form-fields{display:flex;flex-direction:column;gap:.75rem;margin-bottom:1rem}.meshboard-manager-dialog .create-form .form-fields kendo-textbox,.meshboard-manager-dialog .create-form .form-fields kendo-textarea{width:100%}.meshboard-manager-dialog .create-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem}.meshboard-manager-dialog .meshboards-list{flex:1;min-height:250px;overflow-y:auto;border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px;background-color:var(--kendo-color-surface, #ffffff)}.meshboard-manager-dialog .meshboards-list .loading-state{display:flex;align-items:center;justify-content:center;padding:2rem;color:var(--kendo-color-subtle, #757575)}.meshboard-manager-dialog .meshboards-list .empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem 2rem;text-align:center}.meshboard-manager-dialog .meshboards-list .empty-state kendo-svg-icon{color:var(--kendo-color-subtle, #9e9e9e);margin-bottom:1rem}.meshboard-manager-dialog .meshboards-list .empty-state h3{margin:.5rem 0;color:var(--kendo-color-on-app-surface, #424242);font-size:1.125rem;font-weight:500}.meshboard-manager-dialog .meshboards-list .empty-state p{margin:0;color:var(--kendo-color-subtle, #757575);font-size:.875rem}.meshboard-manager-dialog .meshboards-list .meshboard-item{border-bottom:1px solid var(--kendo-color-border, #e0e0e0);transition:background-color .2s,box-shadow .2s}.meshboard-manager-dialog .meshboards-list .meshboard-item:last-child{border-bottom:none}.meshboard-manager-dialog .meshboards-list .meshboard-item:not(.active):not(.editing):hover{background-color:var(--kendo-color-base-hover, #f5f5f5)}.meshboard-manager-dialog .meshboards-list .meshboard-item.active{background-color:var(--kendo-color-primary-subtle, #e8eaf6);box-shadow:inset 4px 0 0 var(--kendo-color-primary, #3f51b5)}.meshboard-manager-dialog .meshboards-list .meshboard-item.editing{background-color:var(--kendo-color-surface-alt, #fafafa)}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content{display:flex;align-items:center;gap:1rem;padding:1rem;cursor:pointer}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:8px;background-color:var(--kendo-color-surface-alt, #f5f5f5);color:var(--kendo-color-primary, #3f51b5)}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-icon kendo-svg-icon{color:inherit}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-info{flex:1;min-width:0}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-info .item-name{margin:0 0 .25rem;font-size:1rem;font-weight:500;color:var(--kendo-color-on-app-surface, #212121);display:flex;align-items:center;gap:.5rem}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-info .item-name .active-badge{display:inline-block;padding:.125rem .5rem;font-size:.75rem;font-weight:600;color:var(--kendo-color-on-primary, #ffffff);background-color:var(--kendo-color-primary, #3f51b5);border-radius:12px}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-info .item-description{margin:0;font-size:.875rem;color:var(--kendo-color-subtle, #757575);line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-actions{flex-shrink:0;display:flex;gap:.25rem;opacity:.5;transition:opacity .2s}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content:hover .item-actions{opacity:1}.meshboard-manager-dialog .meshboards-list .meshboard-item.active .item-content .item-icon{background-color:var(--kendo-color-primary, #3f51b5);color:var(--kendo-color-on-primary, #ffffff)}.meshboard-manager-dialog .meshboards-list .meshboard-item:not(.active) .item-content:after{content:\"Click to switch\";font-size:.75rem;color:var(--kendo-color-subtle, #9e9e9e);opacity:0;transition:opacity .2s;white-space:nowrap}.meshboard-manager-dialog .meshboards-list .meshboard-item:not(.active):hover .item-content:after{opacity:1}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit{padding:1rem}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit .edit-fields{display:flex;flex-direction:column;gap:.75rem;margin-bottom:.75rem}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit .edit-fields kendo-textbox,.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit .edit-fields kendo-textarea{width:100%}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit .edit-actions{display:flex;justify-content:flex-end;gap:.5rem}.meshboard-manager-dialog .dialog-actions{display:flex;justify-content:flex-end;gap:.5rem;padding-top:.75rem;border-top:1px solid var(--kendo-color-border, #e0e0e0);flex-shrink:0;margin-bottom:.5rem}.meshboards-list::-webkit-scrollbar{width:8px}.meshboards-list::-webkit-scrollbar-track{background:var(--kendo-color-surface-alt, #f5f5f5)}.meshboards-list::-webkit-scrollbar-thumb{background:var(--kendo-color-border, #e0e0e0);border-radius:4px}.meshboards-list::-webkit-scrollbar-thumb:hover{background:var(--kendo-color-subtle, #9e9e9e)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
31590
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardManagerDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31591
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: MeshBoardManagerDialogComponent, isStandalone: true, selector: "mm-meshboard-manager-dialog", ngImport: i0, template: "<div class=\"meshboard-manager-dialog\">\n <!-- Header with Create/Import Buttons -->\n <div class=\"dialog-header\">\n <p class=\"dialog-description\">Manage your MeshBoards</p>\n <div class=\"header-actions\">\n @if (canExport) {\n <button\n kendoButton\n [svgIcon]=\"uploadIcon\"\n (click)=\"triggerImport()\"\n [disabled]=\"isCreating() || isLoading() || isImporting()\"\n fillMode=\"outline\">\n Import\n </button>\n }\n <button\n kendoButton\n [svgIcon]=\"plusIcon\"\n (click)=\"startCreate()\"\n [disabled]=\"isCreating() || isLoading()\"\n themeColor=\"primary\">\n New MeshBoard\n </button>\n </div>\n </div>\n\n <!-- Create New MeshBoard Form -->\n @if (isCreating()) {\n <div class=\"create-form\">\n <h4 class=\"form-title\">Create New MeshBoard</h4>\n <div class=\"form-fields\">\n <kendo-textbox\n [(ngModel)]=\"newName\"\n placeholder=\"MeshBoard name\"\n [disabled]=\"isLoading()\">\n </kendo-textbox>\n <kendo-textarea\n [(ngModel)]=\"newDescription\"\n placeholder=\"Description (optional)\"\n [rows]=\"2\"\n [disabled]=\"isLoading()\">\n </kendo-textarea>\n </div>\n <div class=\"form-actions\">\n <button\n kendoButton\n [svgIcon]=\"xIcon\"\n (click)=\"cancelCreate()\"\n [disabled]=\"isLoading()\"\n fillMode=\"flat\"\n size=\"small\">\n Cancel\n </button>\n <button\n kendoButton\n [svgIcon]=\"checkIcon\"\n (click)=\"create()\"\n [disabled]=\"newName().trim().length === 0 || isLoading()\"\n themeColor=\"primary\"\n size=\"small\">\n Create\n </button>\n </div>\n </div>\n }\n\n <!-- MeshBoards List -->\n <div class=\"meshboards-list\">\n @if (isLoading()) {\n <div class=\"loading-state\">\n <span class=\"k-loading-text\">Loading...</span>\n </div>\n } @else if (hasMeshBoards()) {\n @for (item of meshBoards(); track item.rtId) {\n <div\n class=\"meshboard-item\"\n [class.active]=\"isActive(item)\"\n [class.editing]=\"isEditing(item)\">\n\n @if (!isEditing(item)) {\n <!-- Display Mode -->\n <div class=\"item-content\" (click)=\"switchTo(item)\">\n <div class=\"item-icon\">\n <kendo-svg-icon [icon]=\"gridLayoutIcon\" size=\"large\"></kendo-svg-icon>\n </div>\n <div class=\"item-info\">\n <h4 class=\"item-name\">\n {{ item.name }}\n @if (isActive(item)) {\n <span class=\"active-badge\">Active</span>\n }\n </h4>\n @if (getDisplayDescription(item)) {\n <p class=\"item-description\">{{ getDisplayDescription(item) }}</p>\n }\n </div>\n <div class=\"item-actions\">\n @if (canExport) {\n <button\n kendoButton\n [svgIcon]=\"downloadIcon\"\n (click)=\"exportMeshBoard(item, $event)\"\n [disabled]=\"isLoading() || isExporting()\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Export\">\n </button>\n }\n <button\n kendoButton\n [svgIcon]=\"copyIcon\"\n (click)=\"duplicate(item); $event.stopPropagation()\"\n [disabled]=\"isLoading() || isDuplicating()\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Duplicate\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"pencilIcon\"\n (click)=\"startEdit(item); $event.stopPropagation()\"\n [disabled]=\"isLoading()\"\n fillMode=\"flat\"\n size=\"small\"\n title=\"Edit\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"trashIcon\"\n (click)=\"delete(item); $event.stopPropagation()\"\n [disabled]=\"isLoading()\"\n fillMode=\"flat\"\n size=\"small\"\n themeColor=\"error\"\n title=\"Delete\">\n </button>\n </div>\n </div>\n } @else {\n <!-- Edit Mode -->\n <div class=\"item-edit\">\n <div class=\"edit-fields\">\n <kendo-textbox\n [(ngModel)]=\"editingName\"\n placeholder=\"MeshBoard name\"\n [disabled]=\"isLoading()\">\n </kendo-textbox>\n <kendo-textarea\n [(ngModel)]=\"editingDescription\"\n placeholder=\"Description (optional)\"\n [rows]=\"2\"\n [disabled]=\"isLoading()\">\n </kendo-textarea>\n </div>\n <div class=\"edit-actions mm-dialog-actions\">\n <button\n kendoButton\n [svgIcon]=\"xIcon\"\n (click)=\"cancelEdit()\"\n [disabled]=\"isLoading()\"\n fillMode=\"flat\"\n size=\"small\">\n Cancel\n </button>\n <button\n kendoButton\n [svgIcon]=\"checkIcon\"\n (click)=\"saveEdit()\"\n [disabled]=\"editingName().trim().length === 0 || isLoading()\"\n themeColor=\"primary\"\n size=\"small\">\n Save\n </button>\n </div>\n </div>\n }\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <kendo-svg-icon [icon]=\"gridLayoutIcon\" size=\"xlarge\"></kendo-svg-icon>\n <h3>No MeshBoards</h3>\n <p>Create your first MeshBoard to get started.</p>\n </div>\n }\n </div>\n\n <!-- Dialog Actions -->\n <div class=\"dialog-actions mm-dialog-actions\">\n <button kendoButton (click)=\"close()\" fillMode=\"flat\">\n Close\n </button>\n </div>\n</div>\n", styles: [".meshboard-manager-dialog{display:flex;flex-direction:column;gap:.75rem;padding:.75rem .75rem 1.5rem;overflow:hidden}.meshboard-manager-dialog .dialog-header{display:flex;justify-content:space-between;align-items:center;gap:1rem}.meshboard-manager-dialog .dialog-header .dialog-description{margin:0;color:var(--kendo-color-subtle, #757575);font-size:.875rem;flex:1}.meshboard-manager-dialog .dialog-header .header-actions{display:flex;gap:.5rem}.meshboard-manager-dialog .create-form{padding:1rem;background-color:var(--kendo-color-surface-alt, #fafafa);border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px}.meshboard-manager-dialog .create-form .form-title{margin:0 0 1rem;font-size:1rem;font-weight:600;color:var(--kendo-color-on-app-surface, #424242)}.meshboard-manager-dialog .create-form .form-fields{display:flex;flex-direction:column;gap:.75rem;margin-bottom:1rem}.meshboard-manager-dialog .create-form .form-fields kendo-textbox,.meshboard-manager-dialog .create-form .form-fields kendo-textarea{width:100%}.meshboard-manager-dialog .create-form .form-actions{display:flex;justify-content:flex-end;gap:.5rem}.meshboard-manager-dialog .meshboards-list{flex:1;min-height:250px;overflow-y:auto;border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px;background-color:var(--kendo-color-surface, #ffffff)}.meshboard-manager-dialog .meshboards-list .loading-state{display:flex;align-items:center;justify-content:center;padding:2rem;color:var(--kendo-color-subtle, #757575)}.meshboard-manager-dialog .meshboards-list .empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem 2rem;text-align:center}.meshboard-manager-dialog .meshboards-list .empty-state kendo-svg-icon{color:var(--kendo-color-subtle, #9e9e9e);margin-bottom:1rem}.meshboard-manager-dialog .meshboards-list .empty-state h3{margin:.5rem 0;color:var(--kendo-color-on-app-surface, #424242);font-size:1.125rem;font-weight:500}.meshboard-manager-dialog .meshboards-list .empty-state p{margin:0;color:var(--kendo-color-subtle, #757575);font-size:.875rem}.meshboard-manager-dialog .meshboards-list .meshboard-item{border-bottom:1px solid var(--kendo-color-border, #e0e0e0);transition:background-color .2s,box-shadow .2s}.meshboard-manager-dialog .meshboards-list .meshboard-item:last-child{border-bottom:none}.meshboard-manager-dialog .meshboards-list .meshboard-item:not(.active):not(.editing):hover{background-color:var(--kendo-color-base-hover, #f5f5f5)}.meshboard-manager-dialog .meshboards-list .meshboard-item.active{background-color:var(--kendo-color-primary-subtle, #e8eaf6);box-shadow:inset 4px 0 0 var(--kendo-color-primary, #3f51b5)}.meshboard-manager-dialog .meshboards-list .meshboard-item.editing{background-color:var(--kendo-color-surface-alt, #fafafa)}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content{display:flex;align-items:center;gap:1rem;padding:1rem;cursor:pointer}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-icon{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:8px;background-color:var(--kendo-color-surface-alt, #f5f5f5);color:var(--kendo-color-primary, #3f51b5)}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-icon kendo-svg-icon{color:inherit}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-info{flex:1;min-width:0}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-info .item-name{margin:0 0 .25rem;font-size:1rem;font-weight:500;color:var(--kendo-color-on-app-surface, #212121);display:flex;align-items:center;gap:.5rem}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-info .item-name .active-badge{display:inline-block;padding:.125rem .5rem;font-size:.75rem;font-weight:600;color:var(--kendo-color-on-primary, #ffffff);background-color:var(--kendo-color-primary, #3f51b5);border-radius:12px}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-info .item-description{margin:0;font-size:.875rem;color:var(--kendo-color-subtle, #757575);line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content .item-actions{flex-shrink:0;display:flex;gap:.25rem;opacity:.5;transition:opacity .2s}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-content:hover .item-actions{opacity:1}.meshboard-manager-dialog .meshboards-list .meshboard-item.active .item-content .item-icon{background-color:var(--kendo-color-primary, #3f51b5);color:var(--kendo-color-on-primary, #ffffff)}.meshboard-manager-dialog .meshboards-list .meshboard-item:not(.active) .item-content:after{content:\"Click to switch\";font-size:.75rem;color:var(--kendo-color-subtle, #9e9e9e);opacity:0;transition:opacity .2s;white-space:nowrap}.meshboard-manager-dialog .meshboards-list .meshboard-item:not(.active):hover .item-content:after{opacity:1}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit{padding:1rem}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit .edit-fields{display:flex;flex-direction:column;gap:.75rem;margin-bottom:.75rem}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit .edit-fields kendo-textbox,.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit .edit-fields kendo-textarea{width:100%}.meshboard-manager-dialog .meshboards-list .meshboard-item .item-edit .edit-actions{display:flex;justify-content:flex-end;gap:.5rem}.meshboard-manager-dialog .dialog-actions{display:flex;justify-content:flex-end;gap:.5rem;padding-top:.75rem;border-top:1px solid var(--kendo-color-border, #e0e0e0);flex-shrink:0;margin-bottom:.5rem}.meshboards-list::-webkit-scrollbar{width:8px}.meshboards-list::-webkit-scrollbar-track{background:var(--kendo-color-surface-alt, #f5f5f5)}.meshboards-list::-webkit-scrollbar-thumb{background:var(--kendo-color-border, #e0e0e0);border-radius:4px}.meshboards-list::-webkit-scrollbar-thumb:hover{background:var(--kendo-color-subtle, #9e9e9e)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
31013
31592
  }
31014
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardManagerDialogComponent, decorators: [{
31593
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardManagerDialogComponent, decorators: [{
31015
31594
  type: Component,
31016
31595
  args: [{ selector: 'mm-meshboard-manager-dialog', standalone: true, imports: [
31017
31596
  CommonModule,
@@ -31083,8 +31662,8 @@ class EditWidgetDialogComponent {
31083
31662
  onCancel() {
31084
31663
  this.cancelled.emit();
31085
31664
  }
31086
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EditWidgetDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31087
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: EditWidgetDialogComponent, isStandalone: true, selector: "mm-edit-widget-dialog", inputs: { widget: "widget", widgets: "widgets", maxColumns: "maxColumns", gridService: "gridService" }, outputs: { save: "save", cancelled: "cancelled" }, ngImport: i0, template: `
31665
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EditWidgetDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31666
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: EditWidgetDialogComponent, isStandalone: true, selector: "mm-edit-widget-dialog", inputs: { widget: "widget", widgets: "widgets", maxColumns: "maxColumns", gridService: "gridService" }, outputs: { save: "save", cancelled: "cancelled" }, ngImport: i0, template: `
31088
31667
  <kendo-dialog
31089
31668
  title="Edit Widget"
31090
31669
  [minWidth]="350"
@@ -31190,7 +31769,7 @@ class EditWidgetDialogComponent {
31190
31769
  </kendo-dialog>
31191
31770
  `, isInline: true, styles: [".edit-widget-form{display:flex;flex-direction:column;gap:16px;padding:8px 0}.form-field{display:flex;flex-direction:column;gap:4px}.form-field label{font-weight:500;font-size:.875rem;color:var(--kendo-color-on-app-surface, #212529)}.form-row{display:flex;gap:16px}.form-row .form-field{flex:1}.form-field-checkbox{flex-direction:row;align-items:center;gap:8px}.form-field-checkbox label{font-weight:400}.form-hint{font-size:.8rem;opacity:.7;padding:8px 12px;border-left:3px solid var(--kendo-color-primary, #0d6efd);background:var(--kendo-color-surface-alt, rgba(0, 0, 0, .05));border-radius:2px}.form-error{color:var(--kendo-color-error, #dc3545);font-size:.875rem;padding:8px;background:var(--kendo-color-error-subtle, rgba(220, 53, 69, .1));border-radius:4px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox]:not([ngNoCva])[formControlName],input[type=checkbox]:not([ngNoCva])[formControl],input[type=checkbox]:not([ngNoCva])[ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$5.DialogComponent, selector: "kendo-dialog", inputs: ["actions", "actionsLayout", "autoFocusedElement", "closable", "title", "width", "minWidth", "maxWidth", "height", "minHeight", "maxHeight", "animation"], outputs: ["action", "close"], exportAs: ["kendoDialog"] }, { kind: "component", type: i1$5.DialogActionsComponent, selector: "kendo-dialog-actions", inputs: ["actions", "layout"], outputs: ["action"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i3.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "component", type: i3.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i4.DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
31192
31771
  }
31193
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: EditWidgetDialogComponent, decorators: [{
31772
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EditWidgetDialogComponent, decorators: [{
31194
31773
  type: Component,
31195
31774
  args: [{ selector: 'mm-edit-widget-dialog', standalone: true, imports: [
31196
31775
  CommonModule,
@@ -32581,13 +33160,13 @@ class MeshBoardViewComponent {
32581
33160
  return false;
32582
33161
  }
32583
33162
  }
32584
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
32585
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: MeshBoardViewComponent, isStandalone: true, selector: "mm-meshboard-view", providers: [
33163
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33164
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: MeshBoardViewComponent, isStandalone: true, selector: "mm-meshboard-view", providers: [
32586
33165
  { provide: HAS_UNSAVED_CHANGES, useExisting: MeshBoardViewComponent },
32587
33166
  AutoRefreshTimerService
32588
33167
  ], viewQueries: [{ propertyName: "tileLayout", first: true, predicate: TileLayoutComponent, descendants: true }], hostDirectives: [{ directive: i1$8.UnsavedChangesDirective }], ngImport: i0, template: "<div class=\"meshboard-view\">\n @if (isLoading()) {\n <div class=\"loading-container\">\n <div class=\"k-loading-mask\">\n <span class=\"k-loading-text\">Loading MeshBoard...</span>\n <div class=\"k-loading-image\"></div>\n <div class=\"k-loading-color\"></div>\n </div>\n </div>\n } @else if (isModelAvailable() === false) {\n <div class=\"model-unavailable\">\n <div class=\"message-card\">\n <kendo-svg-icon [icon]=\"xIcon\" size=\"xlarge\"></kendo-svg-icon>\n <h2>MeshBoard Not Available</h2>\n <p>The MeshBoard feature requires the CK model 'System.UI' version 1.0.1 or higher.</p>\n <p>Please install the required model in your tenant to use this feature.</p>\n </div>\n </div>\n } @else if (notFoundError()) {\n <div class=\"model-unavailable\">\n <div class=\"message-card\">\n <kendo-svg-icon [icon]=\"xIcon\" size=\"xlarge\"></kendo-svg-icon>\n <h2>MeshBoard Not Found</h2>\n <p>{{ notFoundError() }}</p>\n <p>To create a MeshBoard with a Well-Known Name:</p>\n <ol>\n <li>Go to the <a [routerLink]=\"meshBoardPageLink()\">MeshBoard</a> page</li>\n <li>Open Settings</li>\n <li>Set the \"Well-Known Name\" field</li>\n <li>Save the MeshBoard</li>\n </ol>\n </div>\n </div>\n } @else if (isInitialized()) {\n <!-- Toolbar -->\n <div class=\"meshboard-toolbar\">\n <div class=\"toolbar-left\">\n <h2 class=\"meshboard-title\">{{ config().name }}</h2>\n @if (config().description) {\n <span class=\"meshboard-description\">{{ config().description }}</span>\n }\n </div>\n\n <!-- Time Filter (center) -->\n @if (isTimeFilterEnabled()) {\n <div class=\"toolbar-center\">\n <mm-time-range-picker\n [config]=\"timeFilterConfig()?.pickerConfig ?? {}\"\n [labels]=\"timeRangeLabels()\"\n [initialSelection]=\"initialTimeSelection()\"\n (rangeChange)=\"onTimeRangeChange($event)\"\n (selectionChange)=\"onTimeSelectionChange($event)\">\n </mm-time-range-picker>\n @if (canResetTimeFilter()) {\n <button\n kendoButton\n [svgIcon]=\"undoIcon\"\n (click)=\"resetTimeFilterToDefault()\"\n title=\"Reset to default time filter\"\n fillMode=\"flat\"\n size=\"small\">\n </button>\n }\n </div>\n }\n\n <!-- Entity Selectors -->\n @if (hasEntitySelectors()) {\n @if (isTimeFilterEnabled()) {\n <div class=\"toolbar-separator\"></div>\n }\n <div class=\"toolbar-entity-selectors\">\n <mm-entity-selector-toolbar\n [entitySelectors]=\"entitySelectorsConfig()\"\n (entitySelected)=\"onEntitySelectorSelected($event)\"\n (entityCleared)=\"onEntitySelectorCleared($event)\">\n </mm-entity-selector-toolbar>\n </div>\n }\n\n @if (isTimeFilterEnabled() || hasEntitySelectors()) {\n <div class=\"toolbar-separator\"></div>\n }\n <div class=\"toolbar-right mm-toolbar-actions\">\n @if (!isReadonly()) {\n <!-- Manager Button (icon only) -->\n <button\n kendoButton\n [svgIcon]=\"gridLayoutIcon\"\n (click)=\"openManager()\"\n title=\"Manage MeshBoards\"\n fillMode=\"flat\">\n </button>\n\n <!-- Settings Button (icon only) -->\n <button\n kendoButton\n [svgIcon]=\"gearIcon\"\n (click)=\"openSettings()\"\n title=\"MeshBoard Settings\"\n fillMode=\"flat\">\n </button>\n }\n\n <!-- Refresh Button (icon only) -->\n <button\n kendoButton\n [svgIcon]=\"arrowRotateCwIcon\"\n (click)=\"refresh()\"\n title=\"Refresh All Widgets\"\n fillMode=\"flat\">\n </button>\n\n @if (!isReadonly()) {\n <!-- Edit Mode Toggle (icon only) -->\n @if (!isEditMode()) {\n <button\n kendoButton\n [svgIcon]=\"pencilIcon\"\n (click)=\"toggleEditMode()\"\n title=\"Enter Edit Mode\"\n fillMode=\"flat\">\n </button>\n } @else {\n <button\n kendoButton\n [svgIcon]=\"xIcon\"\n (click)=\"cancelEdit()\"\n title=\"Cancel Edit Mode\"\n fillMode=\"flat\">\n </button>\n }\n\n <!-- Add Widget Button (with text) -->\n <button\n kendoButton\n [svgIcon]=\"plusIcon\"\n (click)=\"openAddWidget()\"\n title=\"Add Widget\"\n themeColor=\"primary\">\n Add Widget\n </button>\n\n <!-- Save Button (with text) -->\n @if (canSave()) {\n <button\n kendoButton\n [svgIcon]=\"saveIcon\"\n (click)=\"save()\"\n [disabled]=\"isSaving()\"\n title=\"Save MeshBoard\"\n themeColor=\"primary\">\n {{ isSaving() ? 'Saving...' : 'Save' }}\n </button>\n }\n }\n </div>\n </div>\n\n <!-- Entity Selector Hint -->\n @if (unselectedToolbarSelectors().length > 0) {\n <div class=\"entity-selector-hint\">\n <kendo-svg-icon [icon]=\"infoCircleIcon\" size=\"medium\"></kendo-svg-icon>\n <span>\n Please select\n @for (selector of unselectedToolbarSelectors(); track selector.id; let last = $last) {\n <strong>{{ selector.label }}</strong>@if (!last) {, }\n }\n to display dashboard data.\n </span>\n </div>\n }\n\n <!-- Variable Resolution Errors -->\n @if (variableResolutionErrors().length > 0) {\n <div class=\"variable-resolution-errors\">\n <strong>Variable resolution errors:</strong>\n @for (error of variableResolutionErrors(); track error.variableName) {\n <span class=\"error-item\">{{ error.variableName }}: {{ error.message }}</span>\n }\n </div>\n }\n\n <!-- Banner Zone: widgets placed in the banner stack above the grid -->\n @if (isEditMode()) {\n <div class=\"zone-label banner-zone-label\">Banner Zone</div>\n }\n @for (widget of bannerWidgets(); track trackByWidgetId($index, widget); let first = $first; let last = $last) {\n <div class=\"banner-zone-item\" [class.banner-edit]=\"isEditMode()\">\n @if (isEditMode()) {\n <div class=\"banner-edit-header\">\n <span class=\"widget-title\">{{ widget.title }}</span>\n <div class=\"widget-actions\">\n <button\n kendoButton\n [svgIcon]=\"arrowUpIcon\"\n (click)=\"moveBannerUp(widget.id)\"\n fillMode=\"flat\"\n size=\"small\"\n [disabled]=\"first\"\n title=\"Move up\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"arrowDownIcon\"\n (click)=\"moveBannerDown(widget.id)\"\n fillMode=\"flat\"\n size=\"small\"\n [disabled]=\"last\"\n title=\"Move down\">\n </button>\n @if (supportsConfiguration(widget)) {\n <button\n kendoButton\n [svgIcon]=\"linkIcon\"\n (click)=\"openWidgetConfig(widget)\"\n fillMode=\"flat\"\n size=\"small\"\n class=\"config-widget-btn\"\n [class.needs-config]=\"isWidgetUnconfigured(widget)\"\n [title]=\"isWidgetUnconfigured(widget) ? 'Configure data source (required)' : 'Configure data source'\">\n </button>\n }\n <button\n kendoButton\n [svgIcon]=\"gearIcon\"\n (click)=\"openEditWidgetDialog(widget)\"\n fillMode=\"flat\"\n size=\"small\"\n class=\"edit-widget-btn\"\n title=\"Edit widget\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"trashIcon\"\n (click)=\"removeWidget(widget.id)\"\n fillMode=\"flat\"\n size=\"small\"\n class=\"remove-widget-btn\"\n title=\"Delete widget\">\n </button>\n </div>\n </div>\n }\n @if (getWidgetComponentType(widget.type); as componentType) {\n <ng-container *ngComponentOutlet=\"componentType; inputs: { config: widget }\"></ng-container>\n }\n </div>\n }\n\n <!-- MeshBoard Grid -->\n @if (isEditMode()) {\n <div class=\"zone-label grid-zone-label\">Grid Zone</div>\n }\n @if (hasGridWidgets()) {\n <kendo-tilelayout\n [columns]=\"config().columns\"\n [rowHeight]=\"config().rowHeight\"\n [gap]=\"config().gap\"\n [class.has-banners]=\"bannerWidgets().length > 0 && !isEditMode()\"\n [resizable]=\"isEditMode()\"\n [reorderable]=\"isEditMode()\"\n (reorder)=\"onReorder($event)\"\n (resize)=\"onResize($event)\">\n @for (widget of gridWidgets(); track trackByWidgetId($index, widget)) {\n <kendo-tilelayout-item\n [col]=\"widget.col\"\n [row]=\"widget.row\"\n [colSpan]=\"widget.colSpan\"\n [rowSpan]=\"widget.rowSpan\">\n <kendo-tilelayout-item-header>\n <div class=\"widget-header\"\n [class.unconfigured]=\"isWidgetUnconfigured(widget)\"\n [class.chromeless-header]=\"widget.chromeless && !isEditMode()\">\n @if (!(widget.chromeless && !isEditMode())) {\n <span class=\"widget-title\">{{ widget.title }}</span>\n @if (isWidgetUnconfigured(widget)) {\n <span class=\"unconfigured-badge\" title=\"Widget needs configuration\">!</span>\n }\n }\n @if (isEditMode()) {\n <div class=\"widget-actions\" (pointerdown)=\"$event.stopPropagation()\">\n @if (supportsConfiguration(widget)) {\n <button\n kendoButton\n [svgIcon]=\"linkIcon\"\n (click)=\"openWidgetConfig(widget)\"\n fillMode=\"flat\"\n size=\"small\"\n class=\"config-widget-btn\"\n [class.needs-config]=\"isWidgetUnconfigured(widget)\"\n [title]=\"isWidgetUnconfigured(widget) ? 'Configure data source (required)' : 'Configure data source'\">\n </button>\n }\n <button\n kendoButton\n [svgIcon]=\"gearIcon\"\n (click)=\"openEditWidgetDialog(widget)\"\n fillMode=\"flat\"\n size=\"small\"\n class=\"edit-widget-btn\"\n title=\"Edit position\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"copyIcon\"\n (click)=\"duplicateWidget(widget)\"\n fillMode=\"flat\"\n size=\"small\"\n class=\"duplicate-widget-btn\"\n title=\"Duplicate widget\">\n </button>\n <button\n kendoButton\n [svgIcon]=\"trashIcon\"\n (click)=\"removeWidget(widget.id)\"\n fillMode=\"flat\"\n size=\"small\"\n class=\"remove-widget-btn\"\n title=\"Delete widget\">\n </button>\n </div>\n }\n </div>\n </kendo-tilelayout-item-header>\n <kendo-tilelayout-item-body>\n @if (getWidgetComponentType(widget.type); as componentType) {\n <ng-container *ngComponentOutlet=\"componentType; inputs: { config: widget }\"></ng-container>\n } @else {\n <div class=\"widget-error\">\n <p>Unknown widget type: {{ widget.type }}</p>\n </div>\n }\n </kendo-tilelayout-item-body>\n </kendo-tilelayout-item>\n }\n </kendo-tilelayout>\n } @else {\n <div class=\"empty-state\">\n <div class=\"empty-state-content\">\n <kendo-svg-icon [icon]=\"plusIcon\" size=\"xlarge\"></kendo-svg-icon>\n <h3>No Widgets</h3>\n <p>Get started by adding widgets to your MeshBoard.</p>\n <button\n kendoButton\n [svgIcon]=\"plusIcon\"\n (click)=\"openAddWidget()\"\n themeColor=\"primary\">\n Add Your First Widget\n </button>\n </div>\n </div>\n }\n\n <!-- Edit Widget Dialog -->\n @if (showEditWidgetDialog && editingWidget) {\n <mm-edit-widget-dialog\n [widget]=\"editingWidget\"\n [widgets]=\"config().widgets\"\n [maxColumns]=\"config().columns\"\n [gridService]=\"gridService\"\n (save)=\"onEditWidgetSave($event)\"\n (cancelled)=\"closeEditWidgetDialog()\">\n </mm-edit-widget-dialog>\n }\n }\n</div>\n", styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0;height:100%;width:100%}.meshboard-view{display:flex;flex-direction:column;flex:1;min-height:0;width:100%;background-color:var(--kendo-color-surface, #f5f5f5)}.loading-container{display:flex;align-items:center;justify-content:center;height:100%;width:100%}.entity-selector-hint{display:flex;align-items:center;gap:8px;padding:10px 16px;margin-bottom:8px;background:color-mix(in srgb,var(--kendo-color-info, #2196f3) 10%,var(--kendo-color-surface-alt, #fafafa));border:1px solid color-mix(in srgb,var(--kendo-color-info, #2196f3) 40%,transparent);border-radius:4px;font-size:13px;color:var(--kendo-color-on-app-surface, #424242)}.entity-selector-hint strong{color:var(--kendo-color-info, #2196f3)}.variable-resolution-errors{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:8px 16px;margin-bottom:8px;background:color-mix(in srgb,var(--kendo-color-error, #f44336) 10%,var(--kendo-color-surface-alt, #fafafa));border:1px solid var(--kendo-color-error, #f44336);border-radius:4px;font-size:13px;color:var(--kendo-color-on-app-surface, #424242)}.variable-resolution-errors strong{color:var(--kendo-color-error, #f44336)}.variable-resolution-errors .error-item{padding:2px 8px;background:color-mix(in srgb,var(--kendo-color-error, #f44336) 8%,transparent);border-radius:3px;font-family:Consolas,Monaco,monospace;font-size:12px}.model-unavailable{display:flex;align-items:center;justify-content:center;height:100%;width:100%;padding:2rem;overflow:hidden;box-sizing:border-box}.model-unavailable .message-card{text-align:center;max-width:500px;padding:2rem;background:var(--kendo-color-surface-alt, #fafafa);border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:8px;overflow:hidden}.model-unavailable .message-card kendo-svg-icon{color:var(--kendo-color-warning, #ff9800);margin-bottom:1rem}.model-unavailable .message-card h2{margin:1rem 0;color:var(--kendo-color-on-app-surface, #424242)}.model-unavailable .message-card p{margin:.5rem 0;color:var(--kendo-color-subtle, #757575);line-height:1.5}.model-unavailable .message-card ol{text-align:left;margin:1rem 0;padding-left:1.5rem;color:var(--kendo-color-subtle, #757575);line-height:1.8}.model-unavailable .message-card ol li{margin:.25rem 0}.model-unavailable .message-card ol a{color:var(--kendo-color-primary, #3f51b5);text-decoration:none}.model-unavailable .message-card ol a:hover{text-decoration:underline}.meshboard-toolbar{display:flex;justify-content:space-between;align-items:flex-end;padding:1rem 1.5rem;background-color:var(--kendo-color-surface-alt, white);border-bottom:1px solid var(--kendo-color-border, #e0e0e0);gap:1rem;flex-shrink:0}.meshboard-toolbar .toolbar-left{display:flex;align-items:baseline;gap:1rem;flex:1;min-width:0;align-self:center}.meshboard-toolbar .toolbar-left .meshboard-title{margin:0;font-size:1.5rem;font-weight:500;color:var(--kendo-color-on-app-surface, #212121);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.meshboard-toolbar .toolbar-left .meshboard-description{color:var(--kendo-color-subtle, #757575);font-size:.875rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.meshboard-toolbar .toolbar-center{display:flex;justify-content:center;align-items:flex-end;flex-shrink:0}.meshboard-toolbar .toolbar-center mm-time-range-picker ::ng-deep .time-range-picker{gap:.5rem}.meshboard-toolbar .toolbar-separator{width:1px;align-self:stretch;background-color:var(--kendo-color-border, #e0e0e0);flex-shrink:0}.meshboard-toolbar .toolbar-entity-selectors{display:flex;align-items:flex-end;flex-shrink:0}.meshboard-toolbar .toolbar-right{display:flex;gap:.5rem;align-items:center;flex-shrink:0}.empty-state{display:flex;align-items:flex-start;justify-content:center;height:calc(100% - 80px);width:100%;padding-top:4rem}.empty-state .empty-state-content{text-align:center;padding:2rem}.empty-state .empty-state-content kendo-svg-icon{color:var(--kendo-color-subtle, #9e9e9e);margin-bottom:1rem}.empty-state .empty-state-content h3{margin:1rem 0 .5rem;color:var(--kendo-color-on-app-surface, #424242);font-size:1.25rem;font-weight:500}.empty-state .empty-state-content p{margin:0 0 1.5rem;color:var(--kendo-color-subtle, #757575)}kendo-tilelayout{padding:1.5rem;overflow:auto;flex:1;min-height:0}.widget-header{display:flex;justify-content:space-between;align-items:center;width:100%;gap:.5rem}.widget-header.unconfigured{background-color:#ff98001a}.widget-header .widget-title{flex:1;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.widget-header .unconfigured-badge{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background-color:var(--kendo-color-warning, #ff9800);color:#fff;font-size:12px;font-weight:700;flex-shrink:0}.widget-header .widget-actions{display:flex;align-items:center;gap:.25rem;flex-shrink:0}.widget-header .config-widget-btn,.widget-header .edit-widget-btn,.widget-header .remove-widget-btn{opacity:.6;transition:opacity .2s}.widget-header .config-widget-btn:hover,.widget-header .edit-widget-btn:hover,.widget-header .remove-widget-btn:hover{opacity:1}.widget-header .config-widget-btn.needs-config{color:var(--kendo-color-warning, #ff9800);opacity:1}.widget-header .remove-widget-btn{color:var(--kendo-color-error, #f44336)}.widget-error{display:flex;align-items:center;justify-content:center;height:100%;padding:1rem;color:var(--kendo-color-error, #f44336);text-align:center}.meshboard-view.edit-mode kendo-tilelayout-item:hover{box-shadow:0 0 0 2px var(--kendo-color-primary, #3f51b5)}@media(max-width:768px){.meshboard-toolbar{flex-direction:column;align-items:stretch;gap:.75rem}.meshboard-toolbar .toolbar-left{flex-direction:column;align-items:flex-start;gap:.25rem}.meshboard-toolbar .toolbar-right{flex-wrap:wrap;justify-content:flex-end}kendo-tilelayout{padding:1rem}}:host ::ng-deep kendo-tilelayout.has-banners{padding-top:0!important}:host ::ng-deep kendo-tilelayout{padding-bottom:1.5rem!important}.widget-header.chromeless-header{display:none}:host ::ng-deep .k-tilelayout-item-header:has(.chromeless-header){display:none}:host ::ng-deep kendo-tilelayout-item:has(.chromeless-header).k-tilelayout-item,:host ::ng-deep kendo-tilelayout-item:has(.chromeless-header).k-card{border:none;box-shadow:none;background:transparent}:host ::ng-deep kendo-tilelayout-item:has(kendo-dialog),:host ::ng-deep kendo-tilelayout-item:has(kendo-window){z-index:9999}.zone-label{font-size:.65rem;text-transform:uppercase;letter-spacing:1.5px;opacity:.4;padding:6px 1rem 2px;font-weight:600}.banner-zone-item{margin:0;padding:8px 1rem}.banner-zone-item.banner-edit{border:1px dashed var(--kendo-color-border, rgba(255, 255, 255, .2));border-radius:4px;margin:0 1rem 12px;padding:4px 0}.banner-edit-header{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;opacity:.7}.banner-edit-header .widget-title{font-size:.75rem;text-transform:uppercase;letter-spacing:.5px}.banner-edit-header .widget-actions{display:flex;gap:2px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i3$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "ngmodule", type: TileLayoutModule }, { kind: "component", type: i5.TileLayoutComponent, selector: "kendo-tilelayout", inputs: ["columns", "columnWidth", "gap", "reorderable", "resizable", "rowHeight", "autoFlow", "navigable"], outputs: ["reorder", "resize"] }, { kind: "component", type: i5.TileLayoutItemBodyComponent, selector: "kendo-tilelayout-item-body" }, { kind: "component", type: i5.TileLayoutItemComponent, selector: "kendo-tilelayout-item", inputs: ["title", "rowSpan", "colSpan", "order", "col", "row", "reorderable", "resizable"] }, { kind: "component", type: i5.TileLayoutItemHeaderComponent, selector: "kendo-tilelayout-item-header" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i1$4.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon", "variant"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: EditWidgetDialogComponent, selector: "mm-edit-widget-dialog", inputs: ["widget", "widgets", "maxColumns", "gridService"], outputs: ["save", "cancelled"] }, { kind: "component", type: TimeRangePickerComponent, selector: "mm-time-range-picker", inputs: ["config", "labels", "initialSelection"], outputs: ["rangeChange", "rangeChangeISO", "selectionChange"] }, { kind: "component", type: EntitySelectorToolbarComponent, selector: "mm-entity-selector-toolbar", inputs: ["entitySelectors"], outputs: ["entitySelected", "entityCleared"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
32589
33168
  }
32590
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: MeshBoardViewComponent, decorators: [{
33169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: MeshBoardViewComponent, decorators: [{
32591
33170
  type: Component,
32592
33171
  args: [{ selector: 'mm-meshboard-view', standalone: true, imports: [
32593
33172
  CommonModule,