@meshmakers/octo-ui 3.3.770 → 3.3.790

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Component, Injectable, EventEmitter, Output, Input, ElementRef, forwardRef, ViewChild, signal, computed, Directive, input, output, effect, InjectionToken, HostListener, makeEnvironmentProviders } from '@angular/core';
2
+ import { inject, Component, Injectable, EventEmitter, Output, Input, ChangeDetectionStrategy, ElementRef, forwardRef, ViewChild, signal, computed, Directive, input, output, effect, InjectionToken, HostListener, makeEnvironmentProviders } from '@angular/core';
3
3
  import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
4
4
  import { AttributeSelectorService, AttributeValueTypeDto as AttributeValueTypeDto$1, CkTypeSelectorService, CkTypeAttributeService, GetEntitiesByCkTypeDtoGQL, RuntimeEntitySelectDataSource, RuntimeEntityDialogDataSource, SearchFilterTypesDto, SortOrdersDto, FieldFilterOperatorsDto, GraphDirectionDto, GraphQL, AssociationModOptionsDto, GetCkTypesDtoGQL, GetCkModelByIdDtoGQL, LevelMetaData, RtAssociationMetaData, CkTypeMetaData, provideOctoServices } from '@meshmakers/octo-services';
5
5
  import { Roles, provideMmSharedAuth } from '@meshmakers/shared-auth';
@@ -20,7 +20,7 @@ import { IconsModule, SVGIconModule, SVGIconComponent } from '@progress/kendo-an
20
20
  import * as i5 from '@progress/kendo-angular-inputs';
21
21
  import { InputsModule, TextBoxModule, KENDO_INPUTS } from '@progress/kendo-angular-inputs';
22
22
  import { searchIcon, sortAscSmallIcon, sortDescSmallIcon, filterClearIcon, chevronRightIcon, chevronDownIcon, downloadIcon, fileIcon, folderIcon, calendarIcon, checkboxCheckedIcon, listUnorderedIcon, arrowRightIcon, arrowLeftIcon, chevronDoubleRightIcon, chevronDoubleLeftIcon, arrowUpIcon, arrowDownIcon, pencilIcon, trashIcon, copyIcon, plusIcon, minusIcon, dollarIcon, infoCircleIcon, gearIcon, eyeIcon, arrowRotateCcwIcon, folderMoreIcon, folderOpenIcon, locationsIcon, arrowRotateCwIcon, xIcon } from '@progress/kendo-svg-icons';
23
- import { Subject, firstValueFrom, Subscription, of, forkJoin, takeUntil as takeUntil$1, defer, from, map as map$1, catchError as catchError$1, finalize, switchMap as switchMap$1, startWith } from 'rxjs';
23
+ import { Subject, firstValueFrom, Subscription, of, forkJoin, takeUntil as takeUntil$1, catchError as catchError$1, map as map$1, defer, from, finalize, switchMap as switchMap$1, startWith } from 'rxjs';
24
24
  import { debounceTime, distinctUntilChanged, map, switchMap, tap, catchError, takeUntil } from 'rxjs/operators';
25
25
  import { LoaderModule } from '@progress/kendo-angular-indicators';
26
26
  import { isCompositeFilterDescriptor } from '@progress/kendo-data-query';
@@ -242,8 +242,8 @@ class AttributeSortSelectorDialogComponent {
242
242
  onCancel() {
243
243
  this.windowRef.close();
244
244
  }
245
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSortSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
246
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: AttributeSortSelectorDialogComponent, isStandalone: true, selector: "mm-attribute-sort-selector-dialog", host: { attributes: { "data-component": "attribute-sort-selector" } }, ngImport: i0, template: `
245
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSortSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
246
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: AttributeSortSelectorDialogComponent, isStandalone: true, selector: "mm-attribute-sort-selector-dialog", host: { attributes: { "data-component": "attribute-sort-selector" } }, ngImport: i0, template: `
247
247
  <div class="attribute-sort-selector-container">
248
248
  <!-- Filter Section -->
249
249
  <div class="filter-container">
@@ -413,7 +413,7 @@ class AttributeSortSelectorDialogComponent {
413
413
  </div>
414
414
  `, isInline: true, styles: [":host{display:block;height:100%}.attribute-sort-selector-container{display:flex;flex-direction:column;height:100%;padding:16px 20px;box-sizing:border-box;gap:16px}.filter-container{display:flex;gap:12px;flex-shrink:0}.search-input{flex:1}.type-filter-dropdown{width:160px;flex-shrink:0}.lists-container{display:flex;gap:16px;flex:1;min-height:0}.list-section{flex:1;display:flex;flex-direction:column;min-height:0}.list-section h4,.sort-options-section h4{margin:0 0 10px;font-size:.85rem;font-weight:600;flex-shrink:0}.attribute-grid{border-radius:4px;flex:1;min-height:200px}.attribute-grid ::ng-deep .k-grid-table tbody tr{cursor:pointer}.sort-options-section{width:120px;flex-shrink:0;display:flex;flex-direction:column;padding-top:32px}.sort-buttons{display:flex;flex-direction:row;gap:4px}.sort-button{flex:1;min-width:36px;height:36px;padding:0;display:flex;align-items:center;justify-content:center}.add-button{width:100%;margin-top:16px}.sort-display{display:flex;align-items:center;gap:6px}.sort-indicator{font-size:14px;font-weight:700;color:var(--kendo-color-primary, #ff6358)}.action-bar{display:flex;justify-content:flex-end;gap:8px;flex-shrink:0;padding-top:8px;border-top:1px solid var(--kendo-color-border, #dee2e6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "directive", type: i3.SelectionDirective, selector: "[kendoGridSelectBy]" }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i5.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: i5.TextBoxSuffixTemplateDirective, selector: "[kendoTextBoxSuffixTemplate]", inputs: ["showSeparator"] }, { 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: IconsModule }, { kind: "ngmodule", type: WindowModule }] });
415
415
  }
416
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSortSelectorDialogComponent, decorators: [{
416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSortSelectorDialogComponent, decorators: [{
417
417
  type: Component,
418
418
  args: [{ selector: 'mm-attribute-sort-selector-dialog', standalone: true, host: { 'data-component': 'attribute-sort-selector' }, imports: [
419
419
  CommonModule,
@@ -661,10 +661,10 @@ class AttributeSortSelectorDialogService {
661
661
  };
662
662
  }
663
663
  }
664
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSortSelectorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
665
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSortSelectorDialogService });
664
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSortSelectorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
665
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSortSelectorDialogService });
666
666
  }
667
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSortSelectorDialogService, decorators: [{
667
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSortSelectorDialogService, decorators: [{
668
668
  type: Injectable
669
669
  }] });
670
670
 
@@ -848,8 +848,8 @@ class CkTypeSelectorDialogComponent {
848
848
  this.windowRef.close(result);
849
849
  }
850
850
  }
851
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
852
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: CkTypeSelectorDialogComponent, isStandalone: true, selector: "mm-ck-type-selector-dialog", ngImport: i0, template: `
851
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
852
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: CkTypeSelectorDialogComponent, isStandalone: true, selector: "mm-ck-type-selector-dialog", ngImport: i0, template: `
853
853
  <div class="ck-type-selector-container">
854
854
  <div class="filter-container">
855
855
  <div class="filter-row">
@@ -931,7 +931,7 @@ class CkTypeSelectorDialogComponent {
931
931
  </div>
932
932
  `, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%}.ck-type-selector-container{display:flex;flex-direction:column;flex:1;min-height:0;padding:20px;box-sizing:border-box;gap:12px}.filter-container{margin-bottom:16px;flex-shrink:0}.filter-row{display:flex;gap:16px;align-items:flex-end}.filter-item{display:flex;flex-direction:column;gap:4px}.filter-item label{font-size:12px;font-weight:500}.filter-item.flex-grow{flex:1}.filter-item.filter-actions{flex-shrink:0}.filter-input{min-width:180px}.grid-container{flex:1;min-height:0;display:flex;flex-direction:column}.grid-container kendo-grid,.grid-container .type-grid{flex:1;min-height:200px}.type-grid{border-radius:4px}.type-grid ::ng-deep .k-grid-table tbody tr{cursor:pointer}.abstract-type{font-style:italic;opacity:.7}.final-type{font-weight:600}.type-badge{display:inline-block;font-size:10px;padding:1px 6px;border-radius:10px;margin-left:8px;text-transform:uppercase}.type-badge.abstract{background-color:var(--kendo-color-warning, #ffc107);color:var(--kendo-color-on-warning, #000);opacity:.8}.type-badge.final{background-color:var(--kendo-color-success, #28a745);color:var(--kendo-color-on-success, #fff);opacity:.8}.selection-info{margin-top:12px;padding:8px 12px;background:var(--kendo-color-success-subtle, #d4edda);border:1px solid var(--kendo-color-success, #28a745);border-radius:4px;font-size:14px;flex-shrink:0}.dialog-actions{display:flex;justify-content:flex-end;gap:8px;padding:8px 20px 0;flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "directive", type: i3.SelectionDirective, selector: "[kendoGridSelectBy]" }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i5.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: i5.TextBoxSuffixTemplateDirective, selector: "[kendoTextBoxSuffixTemplate]", inputs: ["showSeparator"] }, { 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: "ngmodule", type: IconsModule }, { kind: "ngmodule", type: LoaderModule }, { kind: "ngmodule", type: WindowModule }] });
933
933
  }
934
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeSelectorDialogComponent, decorators: [{
934
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeSelectorDialogComponent, decorators: [{
935
935
  type: Component,
936
936
  args: [{ selector: 'mm-ck-type-selector-dialog', standalone: true, imports: [
937
937
  CommonModule,
@@ -1087,10 +1087,10 @@ class CkTypeSelectorDialogService {
1087
1087
  };
1088
1088
  }
1089
1089
  }
1090
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeSelectorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1091
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeSelectorDialogService });
1090
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeSelectorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1091
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeSelectorDialogService });
1092
1092
  }
1093
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeSelectorDialogService, decorators: [{
1093
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeSelectorDialogService, decorators: [{
1094
1094
  type: Injectable
1095
1095
  }] });
1096
1096
 
@@ -1466,10 +1466,10 @@ class PropertyConverterService {
1466
1466
  const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/;
1467
1467
  return isoDateRegex.test(value) && !isNaN(Date.parse(value));
1468
1468
  }
1469
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropertyConverterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1470
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropertyConverterService, providedIn: 'root' });
1469
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyConverterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1470
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyConverterService, providedIn: 'root' });
1471
1471
  }
1472
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropertyConverterService, decorators: [{
1472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyConverterService, decorators: [{
1473
1473
  type: Injectable,
1474
1474
  args: [{
1475
1475
  providedIn: 'root'
@@ -1487,6 +1487,18 @@ class PropertyValueDisplayComponent {
1487
1487
  binaryDownload = new EventEmitter();
1488
1488
  // Expansion state
1489
1489
  isExpanded = false;
1490
+ // Pre-computed template properties (computed once in ngOnInit)
1491
+ expandableRecord = false;
1492
+ complexType = false;
1493
+ binaryLinkedWithDownload = false;
1494
+ formattedValue = '';
1495
+ recordSummary = '';
1496
+ typeIndicator = '';
1497
+ typeDescription = '';
1498
+ binaryFilename = null;
1499
+ binarySize = null;
1500
+ binaryContentType = null;
1501
+ formattedBinarySize = '';
1490
1502
  PropertyDisplayMode = PropertyDisplayMode;
1491
1503
  AttributeValueTypeDto = AttributeValueTypeDto;
1492
1504
  Array = Array;
@@ -1494,19 +1506,22 @@ class PropertyValueDisplayComponent {
1494
1506
  chevronDownIcon = chevronDownIcon;
1495
1507
  downloadIcon = downloadIcon;
1496
1508
  ngOnInit() {
1497
- // Debug every property value display component creation
1498
- console.log('PropertyValueDisplayComponent ngOnInit:', {
1499
- type: this.type,
1500
- value: this.value,
1501
- valueType: typeof this.value,
1502
- valueStringified: JSON.stringify(this.value),
1503
- isExpandableRecord: this.isExpandableRecord()
1504
- });
1505
- }
1506
- /**
1507
- * Get formatted display value
1508
- */
1509
- getFormattedValue() {
1509
+ this.expandableRecord = this.computeIsExpandableRecord();
1510
+ this.complexType = this.computeIsComplexType();
1511
+ this.binaryLinkedWithDownload = this.computeIsBinaryLinkedWithDownload();
1512
+ this.formattedValue = this.computeFormattedValue();
1513
+ this.recordSummary = this.computeRecordSummary();
1514
+ this.typeIndicator = this.computeTypeIndicator();
1515
+ this.typeDescription = this.computeTypeDescription();
1516
+ if (this.binaryLinkedWithDownload) {
1517
+ const bv = this.value;
1518
+ this.binaryFilename = bv?.filename || null;
1519
+ this.binarySize = bv?.size || null;
1520
+ this.binaryContentType = bv?.contentType || null;
1521
+ this.formattedBinarySize = this.formatFileSize(this.binarySize);
1522
+ }
1523
+ }
1524
+ computeFormattedValue() {
1510
1525
  if (this.value === null) {
1511
1526
  return '<null>';
1512
1527
  }
@@ -1545,49 +1560,13 @@ class PropertyValueDisplayComponent {
1545
1560
  return String(this.value);
1546
1561
  }
1547
1562
  }
1548
- /**
1549
- * Check if this is an expandable record type
1550
- */
1551
- isExpandableRecord() {
1552
- // Comprehensive debug logging
1553
- console.log('PropertyValueDisplay: isExpandableRecord check:', {
1554
- type: this.type,
1555
- typeString: String(this.type),
1556
- typeOf: typeof this.type,
1557
- AttributeValueTypeDtoRecordDto: AttributeValueTypeDto.RecordDto,
1558
- AttributeValueTypeDtoRecordArrayDto: AttributeValueTypeDto.RecordArrayDto,
1559
- typeIsRecordDto: this.type === AttributeValueTypeDto.RecordDto,
1560
- typeIsRecordDtoString: this.type === 'RECORD',
1561
- typeIsRecordArrayDto: this.type === AttributeValueTypeDto.RecordArrayDto,
1562
- value: this.value,
1563
- valueType: typeof this.value,
1564
- valueIsNull: this.value == null,
1565
- valueKeys: this.value && typeof this.value === 'object' ? Object.keys(this.value) : 'not object'
1566
- });
1567
- // Check for record types
1568
- const isRecordDto = this.type === AttributeValueTypeDto.RecordDto;
1569
- const isRecordArrayDto = this.type === AttributeValueTypeDto.RecordArrayDto;
1570
- const isRecordType = isRecordDto || isRecordArrayDto;
1571
- // Simple check: does it have a value?
1572
- const hasValue = this.value != null;
1573
- // Simple check: is it an object or array?
1574
- const isObjectLike = typeof this.value === 'object' && this.value != null;
1575
- const result = isRecordType && hasValue && isObjectLike;
1576
- console.log('PropertyValueDisplay: Expandable result:', {
1577
- isRecordDto,
1578
- isRecordArrayDto,
1579
- isRecordType,
1580
- hasValue,
1581
- isObjectLike,
1582
- finalResult: result
1583
- });
1584
- return result;
1563
+ computeIsExpandableRecord() {
1564
+ const isRecordType = this.type === AttributeValueTypeDto.RecordDto
1565
+ || this.type === AttributeValueTypeDto.RecordArrayDto;
1566
+ return isRecordType && this.value != null && typeof this.value === 'object';
1585
1567
  }
1586
- /**
1587
- * Check if the type is complex (object/array)
1588
- */
1589
- isComplexType() {
1590
- return [
1568
+ computeIsComplexType() {
1569
+ const isComplexDataType = [
1591
1570
  AttributeValueTypeDto.RecordDto,
1592
1571
  AttributeValueTypeDto.RecordArrayDto,
1593
1572
  AttributeValueTypeDto.StringArrayDto,
@@ -1596,11 +1575,13 @@ class PropertyValueDisplayComponent {
1596
1575
  AttributeValueTypeDto.BinaryDto,
1597
1576
  AttributeValueTypeDto.BinaryLinkedDto
1598
1577
  ].includes(this.type);
1578
+ // Only show inline type indicator when the value is actually complex
1579
+ // (not when a simple string is passed for a complex-typed property)
1580
+ if (!isComplexDataType)
1581
+ return false;
1582
+ return this.value != null && typeof this.value === 'object';
1599
1583
  }
1600
- /**
1601
- * Get type indicator text
1602
- */
1603
- getTypeIndicator() {
1584
+ computeTypeIndicator() {
1604
1585
  switch (this.type) {
1605
1586
  case AttributeValueTypeDto.RecordDto:
1606
1587
  return 'RECORD';
@@ -1618,10 +1599,7 @@ class PropertyValueDisplayComponent {
1618
1599
  return this.type.replace('_DTO', '').replace('DTO', '');
1619
1600
  }
1620
1601
  }
1621
- /**
1622
- * Get type description for tooltip
1623
- */
1624
- getTypeDescription() {
1602
+ computeTypeDescription() {
1625
1603
  switch (this.type) {
1626
1604
  case AttributeValueTypeDto.RecordDto:
1627
1605
  return 'Complex object';
@@ -1723,14 +1701,13 @@ class PropertyValueDisplayComponent {
1723
1701
  this.isExpanded = !this.isExpanded;
1724
1702
  }
1725
1703
  /**
1726
- * Get summary text for record header
1704
+ * Compute summary text for record header
1727
1705
  */
1728
- getRecordSummary() {
1706
+ computeRecordSummary() {
1729
1707
  if (this.type === AttributeValueTypeDto.RecordArrayDto && Array.isArray(this.value)) {
1730
1708
  return `Array with ${this.value.length} item${this.value.length !== 1 ? 's' : ''}`;
1731
1709
  }
1732
1710
  if (typeof this.value === 'object' && this.value !== null) {
1733
- // Handle regular objects
1734
1711
  const keys = Object.keys(this.value);
1735
1712
  return `Object with ${keys.length} propert${keys.length !== 1 ? 'ies' : 'y'}`;
1736
1713
  }
@@ -1744,13 +1721,11 @@ class PropertyValueDisplayComponent {
1744
1721
  return [];
1745
1722
  }
1746
1723
  if (Array.isArray(obj) && obj.length > 0 && typeof obj[0] === 'object' && obj[0] !== null && 'id' in obj[0] && obj[0].id === 'ckRecordId') {
1747
- // Handle array of records
1748
1724
  return obj.map((item) => ({
1749
1725
  key: String(item['name']),
1750
1726
  value: item['value']
1751
1727
  }));
1752
1728
  }
1753
- // Handle regular objects
1754
1729
  const record = obj;
1755
1730
  return Object.keys(record).map(key => ({
1756
1731
  key,
@@ -1771,7 +1746,6 @@ class PropertyValueDisplayComponent {
1771
1746
  return Number.isInteger(value) ? AttributeValueTypeDto.IntegerDto : AttributeValueTypeDto.DoubleDto;
1772
1747
  }
1773
1748
  if (typeof value === 'string') {
1774
- // Check if it looks like a date
1775
1749
  if (value.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/)) {
1776
1750
  return AttributeValueTypeDto.DateTimeDto;
1777
1751
  }
@@ -1790,48 +1764,17 @@ class PropertyValueDisplayComponent {
1790
1764
  if (value.length > 0 && typeof value[0] === 'number') {
1791
1765
  return AttributeValueTypeDto.IntegerArrayDto;
1792
1766
  }
1793
- return AttributeValueTypeDto.StringArrayDto; // fallback
1767
+ return AttributeValueTypeDto.StringArrayDto;
1794
1768
  }
1795
1769
  return AttributeValueTypeDto.StringDto;
1796
1770
  }
1797
1771
  // ========== Binary Linked Methods ==========
1798
- /**
1799
- * Check if this is a BINARY_LINKED type with download capability
1800
- */
1801
- isBinaryLinkedWithDownload() {
1772
+ computeIsBinaryLinkedWithDownload() {
1802
1773
  if (this.type !== AttributeValueTypeDto.BinaryLinkedDto) {
1803
1774
  return false;
1804
1775
  }
1805
- // Check if value has binaryId or downloadUri (LargeBinaryInfo structure)
1806
1776
  return !!this.value && typeof this.value === 'object' && ('binaryId' in this.value || 'downloadUri' in this.value);
1807
1777
  }
1808
- /**
1809
- * Get the filename from binary info
1810
- */
1811
- getBinaryFilename() {
1812
- if (!this.value || typeof this.value !== 'object') {
1813
- return null;
1814
- }
1815
- return this.value.filename || null;
1816
- }
1817
- /**
1818
- * Get the file size from binary info
1819
- */
1820
- getBinarySize() {
1821
- if (!this.value || typeof this.value !== 'object') {
1822
- return null;
1823
- }
1824
- return this.value.size || null;
1825
- }
1826
- /**
1827
- * Get the content type from binary info
1828
- */
1829
- getBinaryContentType() {
1830
- if (!this.value || typeof this.value !== 'object') {
1831
- return null;
1832
- }
1833
- return this.value.contentType || null;
1834
- }
1835
1778
  /**
1836
1779
  * Format file size to human readable format
1837
1780
  */
@@ -1853,16 +1796,13 @@ class PropertyValueDisplayComponent {
1853
1796
  */
1854
1797
  onDownload() {
1855
1798
  if (!this.value || typeof this.value !== 'object') {
1856
- console.warn('No binary value available');
1857
1799
  return;
1858
1800
  }
1859
1801
  const binaryValue = this.value;
1860
- // If downloadUri is available, open directly
1861
1802
  if (binaryValue.downloadUri) {
1862
1803
  window.open(binaryValue.downloadUri, '_blank', 'noopener,noreferrer');
1863
1804
  return;
1864
1805
  }
1865
- // Otherwise, emit event for parent to handle (needs to load downloadUri)
1866
1806
  if (binaryValue.binaryId) {
1867
1807
  const event = {
1868
1808
  binaryId: binaryValue.binaryId,
@@ -1871,15 +1811,12 @@ class PropertyValueDisplayComponent {
1871
1811
  };
1872
1812
  this.binaryDownload.emit(event);
1873
1813
  }
1874
- else {
1875
- console.warn('No binaryId or downloadUri available');
1876
- }
1877
1814
  }
1878
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropertyValueDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1879
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: PropertyValueDisplayComponent, isStandalone: true, selector: "mm-property-value-display", inputs: { value: "value", type: "type", displayMode: "displayMode" }, outputs: { binaryDownload: "binaryDownload" }, ngImport: i0, template: `
1815
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyValueDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1816
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: PropertyValueDisplayComponent, isStandalone: true, selector: "mm-property-value-display", inputs: { value: "value", type: "type", displayMode: "displayMode" }, outputs: { binaryDownload: "binaryDownload" }, ngImport: i0, template: `
1880
1817
  <div class="property-value-display" [ngClass]="'type-' + type.toLowerCase()">
1881
1818
 
1882
- @if (isExpandableRecord()) {
1819
+ @if (expandableRecord) {
1883
1820
  <div class="expandable-record">
1884
1821
  <!-- Expand/Collapse Button and Summary -->
1885
1822
  <div class="record-header" (click)="toggleExpansion()">
@@ -1887,9 +1824,9 @@ class PropertyValueDisplayComponent {
1887
1824
  [icon]="isExpanded ? chevronDownIcon : chevronRightIcon"
1888
1825
  class="expand-icon">
1889
1826
  </kendo-svgicon>
1890
- <span class="record-summary">{{ getRecordSummary() }}</span>
1891
- <span class="type-indicator" [title]="getTypeDescription()">
1892
- {{ getTypeIndicator() }}
1827
+ <span class="record-summary">{{ recordSummary }}</span>
1828
+ <span class="type-indicator" [title]="typeDescription">
1829
+ {{ typeIndicator }}
1893
1830
  </span>
1894
1831
  </div>
1895
1832
 
@@ -1929,18 +1866,18 @@ class PropertyValueDisplayComponent {
1929
1866
  </div>
1930
1867
  }
1931
1868
  </div>
1932
- } @else if (isBinaryLinkedWithDownload()) {
1869
+ } @else if (binaryLinkedWithDownload) {
1933
1870
  <!-- Binary Linked with download capability -->
1934
1871
  <div class="binary-linked-display">
1935
1872
  <div class="binary-info">
1936
- @if (getBinaryFilename()) {
1937
- <span class="filename">{{ getBinaryFilename() }}</span>
1873
+ @if (binaryFilename) {
1874
+ <span class="filename">{{ binaryFilename }}</span>
1938
1875
  }
1939
- @if (getBinarySize()) {
1940
- <span class="file-size">({{ formatFileSize(getBinarySize()) }})</span>
1876
+ @if (binarySize) {
1877
+ <span class="file-size">({{ formattedBinarySize }})</span>
1941
1878
  }
1942
- @if (getBinaryContentType()) {
1943
- <span class="content-type">{{ getBinaryContentType() }}</span>
1879
+ @if (binaryContentType) {
1880
+ <span class="content-type">{{ binaryContentType }}</span>
1944
1881
  }
1945
1882
  </div>
1946
1883
  <button
@@ -1957,31 +1894,31 @@ class PropertyValueDisplayComponent {
1957
1894
  <!-- Non-expandable value display -->
1958
1895
  @switch (displayMode) {
1959
1896
  @case (PropertyDisplayMode.Json) {
1960
- <pre class="json-display">{{ getFormattedValue() }}</pre>
1897
+ <pre class="json-display">{{ formattedValue }}</pre>
1961
1898
  }
1962
1899
  @case (PropertyDisplayMode.Text) {
1963
- <span class="text-display" [innerHTML]="getFormattedValue()"></span>
1900
+ <span class="text-display" [innerHTML]="formattedValue"></span>
1964
1901
  }
1965
1902
  @default {
1966
- <span class="default-display">{{ getFormattedValue() }}</span>
1903
+ <span class="default-display">{{ formattedValue }}</span>
1967
1904
  }
1968
1905
  }
1969
1906
 
1970
- @if (isComplexType() && !isExpandableRecord()) {
1971
- <span class="type-indicator" [title]="getTypeDescription()">
1972
- {{ getTypeIndicator() }}
1907
+ @if (complexType && !expandableRecord) {
1908
+ <span class="type-indicator" [title]="typeDescription">
1909
+ {{ typeIndicator }}
1973
1910
  </span>
1974
1911
  }
1975
1912
  }
1976
1913
  </div>
1977
- `, isInline: true, styles: [".property-value-display{display:flex;align-items:flex-start;gap:8px;min-height:20px;font-family:inherit;width:100%}.expandable-record{width:100%}.record-header{display:flex;align-items:center;gap:6px;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s}.record-header:hover{background:var(--kendo-color-base-subtle)}.expand-icon{width:16px;height:16px;flex-shrink:0;transition:transform .2s}.record-summary{flex:1;font-size:.9em}.record-content{margin-left:22px;margin-top:8px;border-left:2px solid var(--kendo-color-border);padding-left:12px;background:var(--kendo-color-base-subtle);border-radius:0 4px 4px 0}.nested-properties{display:flex;flex-direction:column;gap:6px;padding:8px}.nested-property{display:flex;align-items:flex-start;gap:8px;min-height:24px}.property-key{font-weight:500;color:var(--kendo-color-primary);min-width:100px;flex-shrink:0;font-size:.9em}.array-item{border:1px solid var(--kendo-color-border);border-radius:4px;margin-bottom:8px;background:transparent}.array-index{display:inline-block;background:var(--kendo-color-primary);color:#fff;padding:2px 8px;font-size:.8em;font-weight:700;border-radius:4px 0;margin-bottom:4px}.json-display{font-family:Courier New,monospace;font-size:12px;margin:0;padding:4px 8px;background:var(--kendo-color-base-subtle);border-radius:4px;max-width:300px;overflow:auto}.text-display,.default-display{flex:1;word-break:break-word;overflow-wrap:anywhere}.type-boolean .default-display{font-weight:500}.type-boolean .default-display.value-true{color:#28a745}.type-boolean .default-display.value-false{color:#dc3545}:is(.type-datetime,.type-datetimeoffset) .default-display{font-family:monospace;font-size:.9em}:is(.type-int,.type-integer,.type-double) .default-display{font-family:monospace;text-align:right}.type-indicator{font-size:.75em;padding:2px 6px;background:var(--kendo-color-primary);color:#fff;border-radius:3px;text-transform:uppercase;font-weight:500;flex-shrink:0}.empty-value{color:var(--kendo-color-subtle);font-style:italic}.null-value{color:var(--kendo-color-error);font-style:italic}.binary-linked-display{display:flex;align-items:center;gap:12px;width:100%}.binary-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.filename{font-weight:500;color:var(--kendo-color-on-app-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-size{font-size:.85em;color:var(--kendo-color-subtle);flex-shrink:0}.content-type{font-size:.75em;padding:2px 6px;background:var(--kendo-color-base-subtle);border-radius:3px;color:var(--kendo-color-subtle);flex-shrink:0}\n"], dependencies: [{ kind: "component", type: PropertyValueDisplayComponent, selector: "mm-property-value-display", inputs: ["value", "type", "displayMode"], outputs: ["binaryDownload"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
1914
+ `, isInline: true, styles: [".property-value-display{display:flex;align-items:flex-start;gap:8px;width:100%;min-width:0}.text-display,.default-display{word-break:break-word;white-space:pre-wrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.json-display{font-family:Roboto Mono,monospace;font-size:.8em;white-space:pre-wrap;word-break:break-word;margin:0;flex:1;min-width:0}.type-indicator{font-family:Roboto Mono,monospace;font-size:.7em;padding:1px 5px;background:var(--kendo-color-base-subtle);border-radius:3px;color:var(--kendo-color-subtle);white-space:nowrap;flex-shrink:0}.expandable-record{width:100%}.record-header{display:flex;align-items:center;gap:6px;cursor:pointer;padding:2px 0;border-radius:3px;transition:background-color .15s ease}.record-header:hover{background-color:var(--kendo-color-base-subtle, rgba(0,0,0,.04))}.expand-icon{flex-shrink:0;width:14px;height:14px;color:var(--kendo-color-subtle)}.record-summary{color:var(--kendo-color-subtle);font-size:.85em;font-style:italic;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.record-content{margin-left:20px;padding-left:8px;border-left:1px solid var(--kendo-color-border, #dee2e6)}.array-item{margin:4px 0}.array-index{font-family:Roboto Mono,monospace;font-size:.8em;color:var(--kendo-color-subtle)}.nested-properties{margin-left:8px}.nested-property{display:flex;align-items:flex-start;gap:8px;padding:2px 0}.property-key{font-weight:500;white-space:nowrap;flex-shrink:0;color:var(--kendo-color-subtle);font-size:.85em}.binary-linked-display{display:flex;align-items:center;gap:12px;width:100%}.binary-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.filename{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-size{font-size:.85em;color:var(--kendo-color-subtle);flex-shrink:0}.content-type{font-size:.75em;padding:2px 6px;background:var(--kendo-color-base-subtle);border-radius:3px;color:var(--kendo-color-subtle);flex-shrink:0}\n"], dependencies: [{ kind: "component", type: PropertyValueDisplayComponent, selector: "mm-property-value-display", inputs: ["value", "type", "displayMode"], outputs: ["binaryDownload"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1978
1915
  }
1979
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropertyValueDisplayComponent, decorators: [{
1916
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyValueDisplayComponent, decorators: [{
1980
1917
  type: Component,
1981
- args: [{ selector: 'mm-property-value-display', standalone: true, imports: [CommonModule, SVGIconModule, ButtonModule], template: `
1918
+ args: [{ selector: 'mm-property-value-display', standalone: true, imports: [CommonModule, SVGIconModule, ButtonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
1982
1919
  <div class="property-value-display" [ngClass]="'type-' + type.toLowerCase()">
1983
1920
 
1984
- @if (isExpandableRecord()) {
1921
+ @if (expandableRecord) {
1985
1922
  <div class="expandable-record">
1986
1923
  <!-- Expand/Collapse Button and Summary -->
1987
1924
  <div class="record-header" (click)="toggleExpansion()">
@@ -1989,9 +1926,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1989
1926
  [icon]="isExpanded ? chevronDownIcon : chevronRightIcon"
1990
1927
  class="expand-icon">
1991
1928
  </kendo-svgicon>
1992
- <span class="record-summary">{{ getRecordSummary() }}</span>
1993
- <span class="type-indicator" [title]="getTypeDescription()">
1994
- {{ getTypeIndicator() }}
1929
+ <span class="record-summary">{{ recordSummary }}</span>
1930
+ <span class="type-indicator" [title]="typeDescription">
1931
+ {{ typeIndicator }}
1995
1932
  </span>
1996
1933
  </div>
1997
1934
 
@@ -2031,18 +1968,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
2031
1968
  </div>
2032
1969
  }
2033
1970
  </div>
2034
- } @else if (isBinaryLinkedWithDownload()) {
1971
+ } @else if (binaryLinkedWithDownload) {
2035
1972
  <!-- Binary Linked with download capability -->
2036
1973
  <div class="binary-linked-display">
2037
1974
  <div class="binary-info">
2038
- @if (getBinaryFilename()) {
2039
- <span class="filename">{{ getBinaryFilename() }}</span>
1975
+ @if (binaryFilename) {
1976
+ <span class="filename">{{ binaryFilename }}</span>
2040
1977
  }
2041
- @if (getBinarySize()) {
2042
- <span class="file-size">({{ formatFileSize(getBinarySize()) }})</span>
1978
+ @if (binarySize) {
1979
+ <span class="file-size">({{ formattedBinarySize }})</span>
2043
1980
  }
2044
- @if (getBinaryContentType()) {
2045
- <span class="content-type">{{ getBinaryContentType() }}</span>
1981
+ @if (binaryContentType) {
1982
+ <span class="content-type">{{ binaryContentType }}</span>
2046
1983
  }
2047
1984
  </div>
2048
1985
  <button
@@ -2059,24 +1996,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
2059
1996
  <!-- Non-expandable value display -->
2060
1997
  @switch (displayMode) {
2061
1998
  @case (PropertyDisplayMode.Json) {
2062
- <pre class="json-display">{{ getFormattedValue() }}</pre>
1999
+ <pre class="json-display">{{ formattedValue }}</pre>
2063
2000
  }
2064
2001
  @case (PropertyDisplayMode.Text) {
2065
- <span class="text-display" [innerHTML]="getFormattedValue()"></span>
2002
+ <span class="text-display" [innerHTML]="formattedValue"></span>
2066
2003
  }
2067
2004
  @default {
2068
- <span class="default-display">{{ getFormattedValue() }}</span>
2005
+ <span class="default-display">{{ formattedValue }}</span>
2069
2006
  }
2070
2007
  }
2071
2008
 
2072
- @if (isComplexType() && !isExpandableRecord()) {
2073
- <span class="type-indicator" [title]="getTypeDescription()">
2074
- {{ getTypeIndicator() }}
2009
+ @if (complexType && !expandableRecord) {
2010
+ <span class="type-indicator" [title]="typeDescription">
2011
+ {{ typeIndicator }}
2075
2012
  </span>
2076
2013
  }
2077
2014
  }
2078
2015
  </div>
2079
- `, styles: [".property-value-display{display:flex;align-items:flex-start;gap:8px;min-height:20px;font-family:inherit;width:100%}.expandable-record{width:100%}.record-header{display:flex;align-items:center;gap:6px;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s}.record-header:hover{background:var(--kendo-color-base-subtle)}.expand-icon{width:16px;height:16px;flex-shrink:0;transition:transform .2s}.record-summary{flex:1;font-size:.9em}.record-content{margin-left:22px;margin-top:8px;border-left:2px solid var(--kendo-color-border);padding-left:12px;background:var(--kendo-color-base-subtle);border-radius:0 4px 4px 0}.nested-properties{display:flex;flex-direction:column;gap:6px;padding:8px}.nested-property{display:flex;align-items:flex-start;gap:8px;min-height:24px}.property-key{font-weight:500;color:var(--kendo-color-primary);min-width:100px;flex-shrink:0;font-size:.9em}.array-item{border:1px solid var(--kendo-color-border);border-radius:4px;margin-bottom:8px;background:transparent}.array-index{display:inline-block;background:var(--kendo-color-primary);color:#fff;padding:2px 8px;font-size:.8em;font-weight:700;border-radius:4px 0;margin-bottom:4px}.json-display{font-family:Courier New,monospace;font-size:12px;margin:0;padding:4px 8px;background:var(--kendo-color-base-subtle);border-radius:4px;max-width:300px;overflow:auto}.text-display,.default-display{flex:1;word-break:break-word;overflow-wrap:anywhere}.type-boolean .default-display{font-weight:500}.type-boolean .default-display.value-true{color:#28a745}.type-boolean .default-display.value-false{color:#dc3545}:is(.type-datetime,.type-datetimeoffset) .default-display{font-family:monospace;font-size:.9em}:is(.type-int,.type-integer,.type-double) .default-display{font-family:monospace;text-align:right}.type-indicator{font-size:.75em;padding:2px 6px;background:var(--kendo-color-primary);color:#fff;border-radius:3px;text-transform:uppercase;font-weight:500;flex-shrink:0}.empty-value{color:var(--kendo-color-subtle);font-style:italic}.null-value{color:var(--kendo-color-error);font-style:italic}.binary-linked-display{display:flex;align-items:center;gap:12px;width:100%}.binary-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.filename{font-weight:500;color:var(--kendo-color-on-app-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-size{font-size:.85em;color:var(--kendo-color-subtle);flex-shrink:0}.content-type{font-size:.75em;padding:2px 6px;background:var(--kendo-color-base-subtle);border-radius:3px;color:var(--kendo-color-subtle);flex-shrink:0}\n"] }]
2016
+ `, styles: [".property-value-display{display:flex;align-items:flex-start;gap:8px;width:100%;min-width:0}.text-display,.default-display{word-break:break-word;white-space:pre-wrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}.json-display{font-family:Roboto Mono,monospace;font-size:.8em;white-space:pre-wrap;word-break:break-word;margin:0;flex:1;min-width:0}.type-indicator{font-family:Roboto Mono,monospace;font-size:.7em;padding:1px 5px;background:var(--kendo-color-base-subtle);border-radius:3px;color:var(--kendo-color-subtle);white-space:nowrap;flex-shrink:0}.expandable-record{width:100%}.record-header{display:flex;align-items:center;gap:6px;cursor:pointer;padding:2px 0;border-radius:3px;transition:background-color .15s ease}.record-header:hover{background-color:var(--kendo-color-base-subtle, rgba(0,0,0,.04))}.expand-icon{flex-shrink:0;width:14px;height:14px;color:var(--kendo-color-subtle)}.record-summary{color:var(--kendo-color-subtle);font-size:.85em;font-style:italic;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.record-content{margin-left:20px;padding-left:8px;border-left:1px solid var(--kendo-color-border, #dee2e6)}.array-item{margin:4px 0}.array-index{font-family:Roboto Mono,monospace;font-size:.8em;color:var(--kendo-color-subtle)}.nested-properties{margin-left:8px}.nested-property{display:flex;align-items:flex-start;gap:8px;padding:2px 0}.property-key{font-weight:500;white-space:nowrap;flex-shrink:0;color:var(--kendo-color-subtle);font-size:.85em}.binary-linked-display{display:flex;align-items:center;gap:12px;width:100%}.binary-info{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.filename{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-size{font-size:.85em;color:var(--kendo-color-subtle);flex-shrink:0}.content-type{font-size:.75em;padding:2px 6px;background:var(--kendo-color-base-subtle);border-radius:3px;color:var(--kendo-color-subtle);flex-shrink:0}\n"] }]
2080
2017
  }], propDecorators: { value: [{
2081
2018
  type: Input
2082
2019
  }], type: [{
@@ -2229,8 +2166,8 @@ class PropertyGridComponent {
2229
2166
  onBinaryDownload(event) {
2230
2167
  this.binaryDownload.emit(event);
2231
2168
  }
2232
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropertyGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2233
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: PropertyGridComponent, isStandalone: true, selector: "mm-property-grid", inputs: { data: "data", config: "config", showTypeColumn: "showTypeColumn" }, outputs: { propertyChange: "propertyChange", saveRequested: "saveRequested", binaryDownload: "binaryDownload" }, usesOnChanges: true, ngImport: i0, template: `
2169
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2170
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: PropertyGridComponent, isStandalone: true, selector: "mm-property-grid", inputs: { data: "data", config: "config", showTypeColumn: "showTypeColumn" }, outputs: { propertyChange: "propertyChange", saveRequested: "saveRequested", binaryDownload: "binaryDownload" }, usesOnChanges: true, ngImport: i0, template: `
2234
2171
  <div class="mm-property-grid" [style.height]="config.height || '400px'">
2235
2172
 
2236
2173
  @if (config.showSearch) {
@@ -2314,7 +2251,7 @@ class PropertyGridComponent {
2314
2251
  </div>
2315
2252
  `, isInline: true, styles: [".mm-property-grid{display:flex;flex-direction:column;border:1px solid var(--kendo-color-border);border-radius:4px;overflow:hidden}.search-toolbar{padding:8px;border-bottom:1px solid var(--kendo-color-border);background:var(--kendo-color-base-subtle)}.property-grid{flex:1;border:none}.property-name-cell{display:flex;align-items:center;gap:8px;min-height:24px}.type-icon{width:16px;height:16px;opacity:.7}.property-info{display:flex;align-items:center;gap:4px;flex:1}.property-name{font-weight:500}.required-indicator{color:var(--kendo-color-error);font-weight:700}.readonly-indicator{font-size:12px;opacity:.7}.property-editor{width:100%;min-width:200px}.validation-error{color:var(--kendo-color-error);font-size:.8em;margin-top:4px}.type-badge{font-size:.75em;padding:2px 6px;border-radius:3px;text-transform:uppercase;font-weight:500;background:var(--kendo-color-base-subtle);color:var(--kendo-color-on-base)}.grid-toolbar{padding:8px;border-top:1px solid var(--kendo-color-border);background:var(--kendo-color-base-subtle);display:flex;align-items:center;gap:8px}.changes-indicator{margin-left:auto;font-size:.9em;color:var(--kendo-color-primary);font-style:italic}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i5.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: "ngmodule", type: ButtonsModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "component", type: PropertyValueDisplayComponent, selector: "mm-property-value-display", inputs: ["value", "type", "displayMode"], outputs: ["binaryDownload"] }] });
2316
2253
  }
2317
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PropertyGridComponent, decorators: [{
2254
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyGridComponent, decorators: [{
2318
2255
  type: Component,
2319
2256
  args: [{ selector: 'mm-property-grid', standalone: true, imports: [
2320
2257
  CommonModule,
@@ -2685,8 +2622,8 @@ class CkTypeSelectorInputComponent {
2685
2622
  this.selectCkType(result.selectedCkType);
2686
2623
  }
2687
2624
  }
2688
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeSelectorInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2689
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: CkTypeSelectorInputComponent, isStandalone: true, selector: "mm-ck-type-selector-input", inputs: { placeholder: "placeholder", minSearchLength: "minSearchLength", maxResults: "maxResults", debounceMs: "debounceMs", ckModelIds: "ckModelIds", allowAbstract: "allowAbstract", dialogTitle: "dialogTitle", advancedSearchLabel: "advancedSearchLabel", derivedFromRtCkTypeId: "derivedFromRtCkTypeId", disabled: "disabled", required: "required" }, outputs: { ckTypeSelected: "ckTypeSelected", ckTypeCleared: "ckTypeCleared" }, providers: [
2625
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeSelectorInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2626
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: CkTypeSelectorInputComponent, isStandalone: true, selector: "mm-ck-type-selector-input", inputs: { placeholder: "placeholder", minSearchLength: "minSearchLength", maxResults: "maxResults", debounceMs: "debounceMs", ckModelIds: "ckModelIds", allowAbstract: "allowAbstract", dialogTitle: "dialogTitle", advancedSearchLabel: "advancedSearchLabel", derivedFromRtCkTypeId: "derivedFromRtCkTypeId", disabled: "disabled", required: "required" }, outputs: { ckTypeSelected: "ckTypeSelected", ckTypeCleared: "ckTypeCleared" }, providers: [
2690
2627
  {
2691
2628
  provide: NG_VALUE_ACCESSOR,
2692
2629
  useExisting: forwardRef(() => CkTypeSelectorInputComponent),
@@ -2753,7 +2690,7 @@ class CkTypeSelectorInputComponent {
2753
2690
  </div>
2754
2691
  `, isInline: true, styles: [":host{display:block;width:100%}.ck-type-select-wrapper{position:relative;display:flex;align-items:center;width:100%;gap:4px}.ck-type-select-wrapper.disabled{opacity:.6;pointer-events:none}.ck-type-autocomplete{flex:1;min-width:0}.dialog-button{flex-shrink:0;height:30px;width:30px;padding:0;display:flex;align-items:center;justify-content:center}.ck-type-item{padding:4px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-data-message{padding:8px 12px;color:var(--kendo-color-subtle);font-style:italic;text-align:center}.advanced-search-footer{display:flex;align-items:center;gap:8px;padding:8px 12px;cursor:pointer;color:var(--kendo-color-primary);border-top:1px solid var(--kendo-color-border);background:var(--kendo-color-surface-alt);transition:background-color .2s}.advanced-search-footer:hover{background:var(--kendo-color-base-hover)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i4.AutoCompleteComponent, selector: "kendo-autocomplete", inputs: ["highlightFirst", "showStickyHeader", "focusableId", "data", "value", "valueField", "placeholder", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "loading", "clearButton", "suggest", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoAutoComplete"] }, { kind: "directive", type: i4.FooterTemplateDirective, selector: "[kendoDropDownListFooterTemplate],[kendoComboBoxFooterTemplate],[kendoDropDownTreeFooterTemplate],[kendoMultiColumnComboBoxFooterTemplate],[kendoAutoCompleteFooterTemplate],[kendoMultiSelectFooterTemplate],[kendoMultiSelectTreeFooterTemplate]" }, { kind: "directive", type: i4.ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "directive", type: i4.NoDataTemplateDirective, selector: "[kendoDropDownListNoDataTemplate],[kendoDropDownTreeNoDataTemplate],[kendoComboBoxNoDataTemplate],[kendoMultiColumnComboBoxNoDataTemplate],[kendoAutoCompleteNoDataTemplate],[kendoMultiSelectNoDataTemplate],[kendoMultiSelectTreeNoDataTemplate]" }, { kind: "ngmodule", type: LoaderModule }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: IconsModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "ngmodule", type: SVGIconModule }] });
2755
2692
  }
2756
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeSelectorInputComponent, decorators: [{
2693
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeSelectorInputComponent, decorators: [{
2757
2694
  type: Component,
2758
2695
  args: [{ selector: 'mm-ck-type-selector-input', standalone: true, imports: [
2759
2696
  CommonModule,
@@ -3206,8 +3143,8 @@ class AttributeSelectorDialogComponent {
3206
3143
  this.sortAvailableAttributes();
3207
3144
  this.updateGrids();
3208
3145
  }
3209
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3210
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AttributeSelectorDialogComponent, isStandalone: true, selector: "mm-attribute-selector-dialog", ngImport: i0, template: `
3146
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3147
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: AttributeSelectorDialogComponent, isStandalone: true, selector: "mm-attribute-selector-dialog", ngImport: i0, template: `
3211
3148
  <div class="attribute-selector-container">
3212
3149
  <div class="filter-container">
3213
3150
  <kendo-textbox
@@ -3419,7 +3356,7 @@ class AttributeSelectorDialogComponent {
3419
3356
  </div>
3420
3357
  `, isInline: true, styles: [":host{display:block;height:100%}.attribute-selector-container{display:flex;flex-direction:column;height:100%;padding:16px 20px;box-sizing:border-box;gap:16px}.filter-container{display:flex;gap:12px;flex-shrink:0}.search-input{flex:1}.type-filter-dropdown{width:160px;flex-shrink:0}.options-container{display:flex;align-items:center;gap:8px;font-size:.85rem;flex-shrink:0}.option-label{cursor:pointer}.depth-input{width:90px}.lists-container{display:flex;gap:16px;flex:1;min-height:0}.list-section{flex:1;display:flex;flex-direction:column;min-height:0}.list-section h4{margin:0 0 10px;font-size:.85rem;font-weight:600;flex-shrink:0}.attribute-grid{border-radius:4px;flex:1;min-height:200px}.attribute-grid ::ng-deep .k-grid-table tbody tr{cursor:pointer}.action-buttons{display:flex;flex-direction:column;gap:8px;justify-content:center;padding:32px 8px 0}.separator{height:1px;background-color:var(--kendo-color-border, #dee2e6);margin:8px 0}.order-buttons{display:flex;flex-direction:column;gap:8px;justify-content:center;padding:32px 8px 0}.order-number{color:var(--kendo-color-primary, #ff6358);font-weight:600;margin-right:8px;min-width:24px;display:inline-block}.single-select-container{flex:1;min-height:0;display:flex;flex-direction:column}.single-select-container .attribute-grid{flex:1}.action-bar{display:flex;justify-content:flex-end;gap:8px;flex-shrink:0;padding-top:8px;border-top:1px solid var(--kendo-color-border, #dee2e6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "directive", type: i3.SelectionDirective, selector: "[kendoGridSelectBy]" }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i5.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: i5.TextBoxSuffixTemplateDirective, selector: "[kendoTextBoxSuffixTemplate]", inputs: ["showSeparator"] }, { kind: "component", type: i5.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: i5.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { 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: IconsModule }, { kind: "ngmodule", type: WindowModule }] });
3421
3358
  }
3422
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSelectorDialogComponent, decorators: [{
3359
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSelectorDialogComponent, decorators: [{
3423
3360
  type: Component,
3424
3361
  args: [{ selector: 'mm-attribute-selector-dialog', standalone: true, imports: [
3425
3362
  CommonModule,
@@ -3718,10 +3655,10 @@ class AttributeSelectorDialogService {
3718
3655
  };
3719
3656
  }
3720
3657
  }
3721
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSelectorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3722
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSelectorDialogService, providedIn: 'root' });
3658
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSelectorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3659
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSelectorDialogService, providedIn: 'root' });
3723
3660
  }
3724
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeSelectorDialogService, decorators: [{
3661
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeSelectorDialogService, decorators: [{
3725
3662
  type: Injectable,
3726
3663
  args: [{
3727
3664
  providedIn: 'root'
@@ -3865,8 +3802,8 @@ class RuntimeEntityVariableDialogComponent {
3865
3802
  return true;
3866
3803
  return false;
3867
3804
  }
3868
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeEntityVariableDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3869
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: RuntimeEntityVariableDialogComponent, isStandalone: true, selector: "mm-runtime-entity-variable-dialog", ngImport: i0, template: `
3805
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeEntityVariableDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3806
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: RuntimeEntityVariableDialogComponent, isStandalone: true, selector: "mm-runtime-entity-variable-dialog", ngImport: i0, template: `
3870
3807
  <div class="dialog-content">
3871
3808
  <div class="form-row">
3872
3809
  <label class="form-label">CK Type</label>
@@ -3948,7 +3885,7 @@ class RuntimeEntityVariableDialogComponent {
3948
3885
  </div>
3949
3886
  `, isInline: true, styles: [".dialog-content{display:flex;flex-direction:column;gap:16px;padding:16px 20px}.form-row{display:flex;flex-direction:column;gap:4px}.form-label{font-size:12px;font-weight:600;color:var(--kendo-color-subtle, #666)}.mappings-grid{border:1px solid var(--kendo-color-border, #e0e0e0);border-radius:4px;background:var(--kendo-color-surface-alt, #fafafa)}.grid-header{display:grid;grid-template-columns:1fr 1fr 100px 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)}.grid-row{display:grid;grid-template-columns:1fr 1fr 100px 40px;gap:.5rem;padding:.5rem .75rem;align-items:start;border-bottom:1px solid var(--kendo-color-border, #e0e0e0)}.grid-row:last-child{border-bottom:none}.col-name{display:flex;flex-direction:column;gap:2px}.col-path,.col-type{font-size:13px;padding-top:6px;color:var(--kendo-color-on-app-surface, #424242)}.col-actions{display:flex;justify-content:center;padding-top:2px}.error-text{font-size:11px;color:var(--kendo-color-error, #f44336)}.dialog-actions{display:flex;justify-content:flex-end;gap:8px;padding-top:8px;border-top:1px solid var(--kendo-color-border, #e0e0e0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i5.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: GridModule }, { kind: "ngmodule", type: IconsModule }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "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"] }] });
3950
3887
  }
3951
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeEntityVariableDialogComponent, decorators: [{
3888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeEntityVariableDialogComponent, decorators: [{
3952
3889
  type: Component,
3953
3890
  args: [{ selector: 'mm-runtime-entity-variable-dialog', standalone: true, imports: [
3954
3891
  CommonModule,
@@ -4083,10 +4020,10 @@ class RuntimeEntityVariableDialogService {
4083
4020
  return { confirmed: false };
4084
4021
  }
4085
4022
  }
4086
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeEntityVariableDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4087
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeEntityVariableDialogService, providedIn: 'root' });
4023
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeEntityVariableDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4024
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeEntityVariableDialogService, providedIn: 'root' });
4088
4025
  }
4089
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeEntityVariableDialogService, decorators: [{
4026
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeEntityVariableDialogService, decorators: [{
4090
4027
  type: Injectable,
4091
4028
  args: [{
4092
4029
  providedIn: 'root'
@@ -4272,8 +4209,8 @@ class EntityIdInfoComponent {
4272
4209
  this.notificationService.showError('Failed to copy to clipboard');
4273
4210
  }
4274
4211
  }
4275
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityIdInfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4276
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: EntityIdInfoComponent, isStandalone: true, selector: "mm-entity-id-info", inputs: { rtId: "rtId", rtCkTypeId: "rtCkTypeId", ckTypeId: "ckTypeId" }, ngImport: i0, template: `
4212
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityIdInfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4213
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: EntityIdInfoComponent, isStandalone: true, selector: "mm-entity-id-info", inputs: { rtId: "rtId", rtCkTypeId: "rtCkTypeId", ckTypeId: "ckTypeId" }, ngImport: i0, template: `
4277
4214
  <kendo-dropdownbutton
4278
4215
  [data]="copyOptions"
4279
4216
  [svgIcon]="copyIcon"
@@ -4291,7 +4228,7 @@ class EntityIdInfoComponent {
4291
4228
  </kendo-dropdownbutton>
4292
4229
  `, isInline: true, styles: [":host{display:inline-block}.copy-item{display:flex;flex-direction:column;gap:2px;padding:8px 12px;width:100%}.copy-label{font-size:.7rem;font-weight:600;color:var(--kendo-color-primary, #64ceb9);text-transform:uppercase;letter-spacing:.5px}.copy-value{font-family:Roboto Mono,monospace;font-size:.75rem;color:var(--kendo-color-subtle, #9292a6);word-break:break-all}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3$1.DropDownButtonComponent, selector: "kendo-dropdownbutton", inputs: ["arrowIcon", "icon", "svgIcon", "iconClass", "imageUrl", "textField", "data", "size", "rounded", "fillMode", "themeColor", "buttonAttributes"], outputs: ["itemClick", "focus", "blur"], exportAs: ["kendoDropDownButton"] }, { kind: "directive", type: i3$1.ButtonItemTemplateDirective, selector: "[kendoDropDownButtonItemTemplate],[kendoSplitButtonItemTemplate]" }, { kind: "ngmodule", type: SVGIconModule }] });
4293
4230
  }
4294
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityIdInfoComponent, decorators: [{
4231
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityIdInfoComponent, decorators: [{
4295
4232
  type: Component,
4296
4233
  args: [{ selector: 'mm-entity-id-info', standalone: true, imports: [
4297
4234
  CommonModule,
@@ -4817,8 +4754,8 @@ class FieldFilterEditorComponent {
4817
4754
  }
4818
4755
  return values;
4819
4756
  }
4820
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: FieldFilterEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4821
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: FieldFilterEditorComponent, isStandalone: true, selector: "mm-field-filter-editor", inputs: { availableAttributes: "availableAttributes", ckTypeId: "ckTypeId", hideNavigationProperties: "hideNavigationProperties", attributePaths: "attributePaths", enableVariables: "enableVariables", availableVariables: "availableVariables", filters: "filters" }, outputs: { filtersChange: "filtersChange" }, usesOnChanges: true, ngImport: i0, template: `
4757
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FieldFilterEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4758
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: FieldFilterEditorComponent, isStandalone: true, selector: "mm-field-filter-editor", inputs: { availableAttributes: "availableAttributes", ckTypeId: "ckTypeId", hideNavigationProperties: "hideNavigationProperties", attributePaths: "attributePaths", enableVariables: "enableVariables", availableVariables: "availableVariables", filters: "filters" }, outputs: { filtersChange: "filtersChange" }, usesOnChanges: true, ngImport: i0, template: `
4822
4759
  <div class="field-filter-editor">
4823
4760
  @if (ckTypeId && !hideNavigationProperties) {
4824
4761
  <div class="attribute-options">
@@ -5117,7 +5054,7 @@ class FieldFilterEditorComponent {
5117
5054
  </div>
5118
5055
  `, isInline: true, styles: [".field-filter-editor{display:flex;flex-direction:column;gap:10px}.attribute-options{display:flex;align-items:center;gap:16px;font-size:.85rem}.inline-checkbox{display:flex;align-items:center;gap:6px;cursor:pointer;font-weight:400}.inline-field{display:flex;align-items:center;gap:6px;font-weight:400}.depth-input{width:80px}.loading-hint{font-size:.8rem;color:var(--kendo-color-subtle, #6c757d)}.toolbar{display:flex;gap:10px;margin-bottom:5px}.filter-grid{border:1px solid #d5d5d5}.filter-grid ::ng-deep .k-grid-header .k-header{font-weight:600}.checkbox-column{text-align:center}.attribute-dropdown,.operator-dropdown,.attribute-input,.value-input{width:100%}.attribute-item{display:flex;justify-content:space-between;align-items:center;width:100%}.attribute-path{flex:1}.attribute-type{font-size:11px;color:#888;margin-left:8px;padding:2px 6px;background:#f0f0f0;border-radius:3px}.empty-state{padding:40px;text-align:center;border:1px dashed;border-radius:8px;font-family:Montserrat,sans-serif;font-size:.9rem}.empty-state p{margin:0}.value-cell{display:flex;gap:4px;align-items:center}.value-cell .value-input{flex:1}.variable-toggle{flex-shrink:0}.variable-item{display:flex;flex-direction:column;gap:2px}.variable-name{font-family:monospace;font-weight:500}.variable-label{font-size:11px;color:var(--kendo-color-subtle, #888)}.variable-value{font-family:monospace;color:var(--kendo-color-primary, #0d6efd)}.variable-placeholder{color:var(--kendo-color-subtle, #888)}.variable-dropdown ::ng-deep .k-input-value-text{font-family:monospace}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i3.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "adaptiveMode", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "showInactiveTools", "isDetailExpanded", "isGroupExpanded", "dataLayoutMode"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "gridStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "directive", type: i3.SelectionDirective, selector: "[kendoGridSelectBy]" }, { kind: "component", type: i3.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i3.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "directive", type: i3.HeaderTemplateDirective, selector: "[kendoGridHeaderTemplate]" }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { 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: "directive", type: i4.ValueTemplateDirective, selector: "[kendoDropDownListValueTemplate],[kendoDropDownTreeValueTemplate]" }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i5.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: i5.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: i5.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }, { kind: "ngmodule", type: DateInputsModule }, { kind: "component", type: i7.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: IconsModule }, { kind: "ngmodule", type: PopupModule }, { kind: "ngmodule", type: IntlModule }] });
5119
5056
  }
5120
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: FieldFilterEditorComponent, decorators: [{
5057
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FieldFilterEditorComponent, decorators: [{
5121
5058
  type: Component,
5122
5059
  args: [{ selector: 'mm-field-filter-editor', standalone: true, imports: [
5123
5060
  CommonModule,
@@ -5462,8 +5399,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
5462
5399
  */
5463
5400
  class OctoLoaderComponent {
5464
5401
  size = 'medium';
5465
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: OctoLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5466
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: OctoLoaderComponent, isStandalone: true, selector: "mm-octo-loader", inputs: { size: "size" }, ngImport: i0, template: `
5402
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: OctoLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5403
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: OctoLoaderComponent, isStandalone: true, selector: "mm-octo-loader", inputs: { size: "size" }, ngImport: i0, template: `
5467
5404
  <div class="octo-loader" [class.octo-loader--small]="size === 'small'" [class.octo-loader--medium]="size === 'medium'">
5468
5405
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="-22 -8 112 118" class="octo-loader__svg" overflow="visible">
5469
5406
  <!-- Orbit track -->
@@ -5554,7 +5491,7 @@ class OctoLoaderComponent {
5554
5491
  </div>
5555
5492
  `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;color:var(--kendo-color-primary, #64ceb9)}.octo-loader{display:inline-flex;align-items:center;justify-content:center}.octo-loader--small .octo-loader__svg{width:24px;height:24px}.octo-loader--medium .octo-loader__svg{width:48px;height:48px}.octo-arm--ol{transform-origin:7px 52.74px;animation:octo-wiggle-outer 1.2s ease-in-out infinite}.octo-arm--or{transform-origin:56px 52.74px;animation:octo-wiggle-outer 1.2s ease-in-out infinite;animation-delay:-.6s}.octo-leg--left{transform-origin:21.8px 52.74px;animation:octo-wiggle-inner 1s ease-in-out infinite}.octo-leg--center{transform-origin:31.5px 52.74px;animation:octo-wiggle-inner 1s ease-in-out infinite reverse;animation-delay:-.33s}.octo-leg--right{transform-origin:46px 52.74px;animation:octo-wiggle-inner 1s ease-in-out infinite;animation-delay:-.66s}@keyframes octo-wiggle-inner{0%,to{transform:rotate(-5deg)}50%{transform:rotate(5deg)}}@keyframes octo-wiggle-outer{0%,to{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}.octo-orbit{stroke:var(--neo-cyan, #00a8dc)}.octo-data{fill:var(--neo-cyan, #00a8dc)}\n"] });
5556
5493
  }
5557
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: OctoLoaderComponent, decorators: [{
5494
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: OctoLoaderComponent, decorators: [{
5558
5495
  type: Component,
5559
5496
  args: [{ selector: 'mm-octo-loader', standalone: true, template: `
5560
5497
  <div class="octo-loader" [class.octo-loader--small]="size === 'small'" [class.octo-loader--medium]="size === 'medium'">
@@ -5675,10 +5612,10 @@ class GetBinaryInfoDtoGQL extends i1$2.Query {
5675
5612
  constructor(apollo) {
5676
5613
  super(apollo);
5677
5614
  }
5678
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetBinaryInfoDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
5679
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetBinaryInfoDtoGQL, providedIn: 'root' });
5615
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetBinaryInfoDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
5616
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetBinaryInfoDtoGQL, providedIn: 'root' });
5680
5617
  }
5681
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetBinaryInfoDtoGQL, decorators: [{
5618
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetBinaryInfoDtoGQL, decorators: [{
5682
5619
  type: Injectable,
5683
5620
  args: [{
5684
5621
  providedIn: 'root'
@@ -5721,10 +5658,10 @@ class GetRuntimeEntityAssociationsByIdDtoGQL extends i1$2.Query {
5721
5658
  constructor(apollo) {
5722
5659
  super(apollo);
5723
5660
  }
5724
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntityAssociationsByIdDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
5725
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntityAssociationsByIdDtoGQL, providedIn: 'root' });
5661
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntityAssociationsByIdDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
5662
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntityAssociationsByIdDtoGQL, providedIn: 'root' });
5726
5663
  }
5727
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntityAssociationsByIdDtoGQL, decorators: [{
5664
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntityAssociationsByIdDtoGQL, decorators: [{
5728
5665
  type: Injectable,
5729
5666
  args: [{
5730
5667
  providedIn: 'root'
@@ -5809,15 +5746,15 @@ class EntityAssociationsDataSourceDirective extends OctoGraphQlDataSource {
5809
5746
  return new FetchResultTyped(transformedItems, totalCount);
5810
5747
  }));
5811
5748
  }
5812
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityAssociationsDataSourceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
5813
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: EntityAssociationsDataSourceDirective, isStandalone: true, selector: "[mmEntityAssociationsDataSource]", providers: [
5749
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityAssociationsDataSourceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
5750
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: EntityAssociationsDataSourceDirective, isStandalone: true, selector: "[mmEntityAssociationsDataSource]", providers: [
5814
5751
  {
5815
5752
  provide: DataSourceBase,
5816
5753
  useExisting: forwardRef(() => EntityAssociationsDataSourceDirective),
5817
5754
  },
5818
5755
  ], exportAs: ["mmEntityAssociationsDataSource"], usesInheritance: true, ngImport: i0 });
5819
5756
  }
5820
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityAssociationsDataSourceDirective, decorators: [{
5757
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityAssociationsDataSourceDirective, decorators: [{
5821
5758
  type: Directive,
5822
5759
  args: [{
5823
5760
  selector: '[mmEntityAssociationsDataSource]',
@@ -6173,8 +6110,8 @@ class EntityDetailViewComponent {
6173
6110
  });
6174
6111
  }
6175
6112
  }
6176
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityDetailViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6177
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: EntityDetailViewComponent, isStandalone: true, selector: "mm-entity-detail-view", inputs: { entity: "entity", loading: "loading", error: "error", showHeader: "showHeader", messages: "messages" }, outputs: { retry: "retry", propertyChange: "propertyChange", navigateToEntity: "navigateToEntity" }, viewQueries: [{ propertyName: "associationsDataSource", first: true, predicate: ["associationsDir"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
6113
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityDetailViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6114
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EntityDetailViewComponent, isStandalone: true, selector: "mm-entity-detail-view", inputs: { entity: "entity", loading: "loading", error: "error", showHeader: "showHeader", messages: "messages" }, outputs: { retry: "retry", propertyChange: "propertyChange", navigateToEntity: "navigateToEntity" }, viewQueries: [{ propertyName: "associationsDataSource", first: true, predicate: ["associationsDir"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
6178
6115
  @if (loading) {
6179
6116
  <div class="loading-state">
6180
6117
  <p>{{ _messages.loadingEntityDetails }}</p>
@@ -6388,7 +6325,7 @@ class EntityDetailViewComponent {
6388
6325
  }
6389
6326
  `, isInline: true, styles: [".loading-state,.error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;text-align:center;min-height:200px}.loading-state .error-message,.error-state .error-message{margin-bottom:16px;font-family:Roboto,sans-serif;color:#e74c3c}.entity-content{flex:1;display:flex;flex-direction:column;gap:24px}.entity-content .basic-info-card{padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.entity-content .basic-info-card:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.entity-content .basic-info-card .basic-info-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:20px}.entity-content .basic-info-card .basic-info-grid .info-item{display:flex;flex-direction:column;gap:8px}.entity-content .basic-info-card .basic-info-grid .info-item label{font-family:Montserrat,sans-serif;font-weight:600;font-size:.75rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80)}.entity-content .basic-info-card .basic-info-grid .info-item .value{font-family:Roboto Mono,monospace;font-size:.875rem;color:rgba(var(--octo-text-color),.9);word-break:break-word;background:var(--deep-sea-40);padding:8px 12px;border-radius:4px;border:1px solid var(--octo-mint-15)}.entity-content .basic-info-card .basic-info-grid .info-item.with-action .value-with-action{display:flex;align-items:center}.entity-content .basic-info-card .basic-info-grid .info-item.with-action .value-with-action .value{flex:1;font-family:Roboto Mono,monospace;font-size:.875rem;color:rgba(var(--octo-text-color),.9);word-break:break-word}.entity-content .entity-tabs{flex:1;min-height:400px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;overflow:hidden;position:relative}.entity-content .entity-tabs:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);z-index:1}.entity-content .entity-tabs ::ng-deep .k-tabstrip{background:transparent}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper{background:linear-gradient(90deg,var(--octo-mint-10),transparent);border-bottom:1px solid var(--octo-mint-20);padding-left:20px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item{background:transparent;border:none;color:rgba(var(--octo-text-color),.7);font-family:Montserrat,sans-serif;font-weight:600;font-size:.8rem;letter-spacing:.5px;text-transform:uppercase;padding:12px 20px;margin-right:4px;border-radius:4px 4px 0 0;transition:all .2s ease}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item:hover{background:var(--octo-mint-10);color:var(--octo-mint)}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item.k-active{background:linear-gradient(180deg,var(--octo-mint-20),transparent);color:var(--octo-mint);border-bottom:2px solid var(--octo-mint);box-shadow:0 0 10px var(--octo-mint-30)}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-content{background:transparent;border:none;padding:0}.entity-content .entity-tabs .tab-content{padding:20px 24px;height:100%;overflow-y:auto}.entity-content .entity-tabs .tab-content .empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 40px;text-align:center}.entity-content .entity-tabs .tab-content .empty-state kendo-svgicon{font-size:64px;margin-bottom:20px;color:var(--octo-mint-40);text-shadow:0 0 20px var(--octo-mint-30)}.entity-content .entity-tabs .tab-content .empty-state p{margin:0;font-family:Montserrat,sans-serif;font-size:.9rem;color:rgba(var(--octo-text-color),.5);letter-spacing:.5px}.entity-content .entity-tabs .tab-content.properties-tab{padding:0;height:100%}.entity-content .entity-tabs .tab-content.properties-tab mm-property-grid{display:block;height:100%;width:100%}.entity-content .entity-tabs .tab-content.associations-tab{display:flex;flex-direction:column;gap:16px;padding:0;height:100%}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding:16px 20px;background:linear-gradient(90deg,var(--octo-mint-05),transparent);border-bottom:1px solid var(--octo-mint-20)}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group{display:flex;align-items:center;gap:10px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group label{font-family:Montserrat,sans-serif;font-weight:600;font-size:.75rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80);white-space:nowrap}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-dropdownlist{width:160px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-textbox{width:220px}.entity-content .entity-tabs .tab-content.associations-tab mm-list-view{flex:1;display:block;height:calc(100% - 70px)}@media(max-width:768px){.entity-content{gap:16px}.entity-content .basic-info-card{padding:16px 20px}.entity-content .basic-info-card .basic-info-grid{grid-template-columns:1fr;gap:16px}.entity-content .entity-tabs{min-height:300px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper{padding-left:12px}.entity-content .entity-tabs ::ng-deep .k-tabstrip .k-tabstrip-items-wrapper .k-tabstrip-items .k-item{padding:10px 14px;font-size:.75rem}.entity-content .entity-tabs .tab-content{padding:16px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar{flex-direction:column;align-items:flex-start;gap:12px}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group{width:100%}.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-dropdownlist,.entity-content .entity-tabs .tab-content.associations-tab .associations-toolbar .filter-group kendo-textbox{width:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TabStripModule }, { kind: "component", type: i1$3.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: i1$3.TabStripTabComponent, selector: "kendo-tabstrip-tab", inputs: ["title", "disabled", "cssClass", "cssStyle", "selected", "closable", "closeIcon", "closeIconClass", "closeSVGIcon"], exportAs: ["kendoTabStripTab"] }, { kind: "directive", type: i1$3.TabContentDirective, selector: "[kendoTabContent]" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: i5$1.SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i1$3.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i1$3.CardBodyComponent, selector: "kendo-card-body" }, { kind: "component", type: i1$3.CardHeaderComponent, selector: "kendo-card-header" }, { 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: TextBoxModule }, { kind: "component", type: i5.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: PropertyGridComponent, selector: "mm-property-grid", inputs: ["data", "config", "showTypeColumn"], outputs: ["propertyChange", "saveRequested", "binaryDownload"] }, { 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: EntityAssociationsDataSourceDirective, selector: "[mmEntityAssociationsDataSource]", exportAs: ["mmEntityAssociationsDataSource"] }] });
6390
6327
  }
6391
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityDetailViewComponent, decorators: [{
6328
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityDetailViewComponent, decorators: [{
6392
6329
  type: Component,
6393
6330
  args: [{ selector: "mm-entity-detail-view", standalone: true, imports: [
6394
6331
  CommonModule,
@@ -6666,10 +6603,10 @@ class GetRuntimeEntityByIdDtoGQL extends i1$2.Query {
6666
6603
  constructor(apollo) {
6667
6604
  super(apollo);
6668
6605
  }
6669
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntityByIdDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
6670
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntityByIdDtoGQL, providedIn: 'root' });
6606
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntityByIdDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
6607
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntityByIdDtoGQL, providedIn: 'root' });
6671
6608
  }
6672
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntityByIdDtoGQL, decorators: [{
6609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntityByIdDtoGQL, decorators: [{
6673
6610
  type: Injectable,
6674
6611
  args: [{
6675
6612
  providedIn: 'root'
@@ -6711,10 +6648,10 @@ class EntityDetailDataSource {
6711
6648
  throw error;
6712
6649
  }
6713
6650
  }
6714
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityDetailDataSource, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6715
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityDetailDataSource, providedIn: 'root' });
6651
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityDetailDataSource, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6652
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityDetailDataSource, providedIn: 'root' });
6716
6653
  }
6717
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityDetailDataSource, decorators: [{
6654
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityDetailDataSource, decorators: [{
6718
6655
  type: Injectable,
6719
6656
  args: [{
6720
6657
  providedIn: 'root',
@@ -6869,8 +6806,8 @@ class EntityDetailComponent {
6869
6806
  // TODO: Implement property change handling
6870
6807
  // This could be used to track modifications and enable save functionality
6871
6808
  }
6872
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6873
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: EntityDetailComponent, isStandalone: true, selector: "mm-entity-detail", ngImport: i0, template: `
6809
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6810
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: EntityDetailComponent, isStandalone: true, selector: "mm-entity-detail", ngImport: i0, template: `
6874
6811
  <div class="entity-detail">
6875
6812
  <div class="entity-detail-header">
6876
6813
  <button
@@ -6904,7 +6841,7 @@ class EntityDetailComponent {
6904
6841
  </div>
6905
6842
  `, isInline: true, styles: [":host{display:block;height:100%;width:100%}.entity-detail{height:100%;display:flex;flex-direction:column;padding:24px;box-sizing:border-box;overflow-y:auto}.entity-detail .entity-detail-header{display:flex;align-items:center;gap:20px;margin-bottom:24px;padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.entity-detail .entity-detail-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.entity-detail .entity-detail-header .header-info{flex:1}.entity-detail .entity-detail-header .header-info .entity-title h2{margin:0 0 8px;font-family:Montserrat,sans-serif;font-size:1.4rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color);text-shadow:0 0 10px rgba(0,0,0,.3)}.entity-detail .entity-detail-header .header-info .entity-type{margin:0;font-family:Roboto Mono,monospace;font-size:.8rem;background:var(--deep-sea-60);padding:6px 12px;border-radius:4px;border:1px solid var(--neo-cyan-30);display:inline-block;color:var(--neo-cyan)}.entity-detail mm-entity-detail-view{flex:1;display:flex;flex-direction:column;overflow-y:auto}@media(max-width:768px){.entity-detail{padding:16px}.entity-detail .entity-detail-header{flex-direction:column;align-items:flex-start;gap:12px;padding:16px 20px}.entity-detail .entity-detail-header .header-info .entity-title h2{font-size:1.1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: EntityDetailViewComponent, selector: "mm-entity-detail-view", inputs: ["entity", "loading", "error", "showHeader", "messages"], outputs: ["retry", "propertyChange", "navigateToEntity"] }] });
6906
6843
  }
6907
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: EntityDetailComponent, decorators: [{
6844
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: EntityDetailComponent, decorators: [{
6908
6845
  type: Component,
6909
6846
  args: [{ selector: 'mm-entity-detail', imports: [
6910
6847
  CommonModule,
@@ -7219,6 +7156,149 @@ const article = {
7219
7156
  viewBox: '0 -960 960 960'
7220
7157
  };
7221
7158
 
7159
+ const GetCkTypeAssociationRolesDocumentDto = gql `
7160
+ query getCkTypeAssociationRoles($ckTypeId: String!) {
7161
+ constructionKit {
7162
+ types(rtCkId: $ckTypeId, first: 1) {
7163
+ items {
7164
+ rtCkTypeId
7165
+ associations {
7166
+ in {
7167
+ all {
7168
+ roleId {
7169
+ fullName
7170
+ semanticVersionedFullName
7171
+ }
7172
+ rtRoleId
7173
+ navigationPropertyName
7174
+ multiplicity
7175
+ targetCkTypeId {
7176
+ fullName
7177
+ }
7178
+ rtTargetCkTypeId
7179
+ }
7180
+ }
7181
+ out {
7182
+ all {
7183
+ roleId {
7184
+ fullName
7185
+ semanticVersionedFullName
7186
+ }
7187
+ rtRoleId
7188
+ navigationPropertyName
7189
+ multiplicity
7190
+ targetCkTypeId {
7191
+ fullName
7192
+ }
7193
+ rtTargetCkTypeId
7194
+ }
7195
+ }
7196
+ }
7197
+ }
7198
+ }
7199
+ }
7200
+ }
7201
+ `;
7202
+ class GetCkTypeAssociationRolesDtoGQL extends i1$2.Query {
7203
+ document = GetCkTypeAssociationRolesDocumentDto;
7204
+ constructor(apollo) {
7205
+ super(apollo);
7206
+ }
7207
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7208
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, providedIn: 'root' });
7209
+ }
7210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkTypeAssociationRolesDtoGQL, decorators: [{
7211
+ type: Injectable,
7212
+ args: [{
7213
+ providedIn: 'root'
7214
+ }]
7215
+ }], ctorParameters: () => [{ type: i1$2.Apollo }] });
7216
+
7217
+ /**
7218
+ * Validates whether a drag-and-drop move (reparenting) is allowed by the CK model.
7219
+ *
7220
+ * Strategy: query the SOURCE type's OUTBOUND association roles and look for a
7221
+ * `System/ParentChild` role whose `rtTargetCkTypeId` matches the destination type.
7222
+ * This means "source entity can have a parent of destination type".
7223
+ */
7224
+ class AssociationValidationService {
7225
+ getCkTypeAssociationRolesGQL = inject(GetCkTypeAssociationRolesDtoGQL);
7226
+ /** Cache: sourceCkTypeId → outbound roles */
7227
+ outRolesCache = new Map();
7228
+ /**
7229
+ * Checks whether an entity of `sourceCkTypeId` can be moved (reparented)
7230
+ * to an entity of `destinationCkTypeId` via a ParentChild association.
7231
+ */
7232
+ async canMove(sourceCkTypeId, destinationCkTypeId) {
7233
+ const outRoles = await this.getOutboundRoles(sourceCkTypeId);
7234
+ // Find a ParentChild outbound role where the target matches the destination type.
7235
+ // Use rtTargetCkTypeId (runtime format) for matching — it matches event.ckTypeId.
7236
+ const matchingRole = outRoles.find((r) => r.rtRoleId === 'System/ParentChild' &&
7237
+ r.rtTargetCkTypeId === destinationCkTypeId);
7238
+ if (matchingRole) {
7239
+ return {
7240
+ allowed: true,
7241
+ rtRoleId: matchingRole.rtRoleId,
7242
+ roleId: matchingRole.roleId,
7243
+ navigationPropertyName: this.toLowerCamelCase(matchingRole.navigationPropertyName),
7244
+ };
7245
+ }
7246
+ return {
7247
+ allowed: false,
7248
+ reason: `CK model does not define a ParentChild association from "${sourceCkTypeId}" to "${destinationCkTypeId}"`,
7249
+ };
7250
+ }
7251
+ /**
7252
+ * Fetches and caches the outbound association roles for a given CK type.
7253
+ */
7254
+ async getOutboundRoles(ckTypeId) {
7255
+ const cached = this.outRolesCache.get(ckTypeId);
7256
+ if (cached) {
7257
+ return cached;
7258
+ }
7259
+ const result = await firstValueFrom(this.getCkTypeAssociationRolesGQL.fetch({
7260
+ variables: { ckTypeId },
7261
+ fetchPolicy: 'network-only',
7262
+ }));
7263
+ const typeData = result.data?.constructionKit?.types?.items?.[0];
7264
+ const rawRoles = typeData?.associations?.out?.all ?? [];
7265
+ const roles = rawRoles
7266
+ .filter((r) => r !== null && r !== undefined)
7267
+ .map((r) => ({
7268
+ roleId: r.roleId?.fullName ?? '',
7269
+ rtRoleId: String(r.rtRoleId ?? ''),
7270
+ targetCkTypeId: r.targetCkTypeId?.fullName ?? '',
7271
+ rtTargetCkTypeId: String(r.rtTargetCkTypeId ?? ''),
7272
+ multiplicity: r.multiplicity ?? '',
7273
+ navigationPropertyName: r.navigationPropertyName ?? '',
7274
+ }));
7275
+ this.outRolesCache.set(ckTypeId, roles);
7276
+ return roles;
7277
+ }
7278
+ /**
7279
+ * Normalizes navigation property name to lowerCamelCase, matching the
7280
+ * backend convention used by typed input types (e.g. "Parent" → "parent").
7281
+ */
7282
+ toLowerCamelCase(name) {
7283
+ if (!name) {
7284
+ return name;
7285
+ }
7286
+ return name.charAt(0).toLowerCase() + name.slice(1);
7287
+ }
7288
+ /** Clears the role cache (e.g. on tenant switch). */
7289
+ clearCache() {
7290
+ this.outRolesCache.clear();
7291
+ }
7292
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AssociationValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7293
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AssociationValidationService, providedIn: 'root' });
7294
+ }
7295
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AssociationValidationService, decorators: [{
7296
+ type: Injectable,
7297
+ args: [{
7298
+ providedIn: 'root',
7299
+ }]
7300
+ }] });
7301
+
7222
7302
  const GetRuntimeEntitiesByTypeDocumentDto = gql `
7223
7303
  query getRuntimeEntitiesByType($ckTypeId: String!, $after: String, $first: Int, $searchFilter: SearchFilter, $fieldFilters: [FieldFilter], $sort: [Sort]) {
7224
7304
  runtime {
@@ -7251,10 +7331,10 @@ class GetRuntimeEntitiesByTypeDtoGQL extends i1$2.Query {
7251
7331
  constructor(apollo) {
7252
7332
  super(apollo);
7253
7333
  }
7254
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntitiesByTypeDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7255
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntitiesByTypeDtoGQL, providedIn: 'root' });
7334
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntitiesByTypeDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7335
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntitiesByTypeDtoGQL, providedIn: 'root' });
7256
7336
  }
7257
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetRuntimeEntitiesByTypeDtoGQL, decorators: [{
7337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetRuntimeEntitiesByTypeDtoGQL, decorators: [{
7258
7338
  type: Injectable,
7259
7339
  args: [{
7260
7340
  providedIn: 'root'
@@ -7315,15 +7395,15 @@ class CkTypeEntitiesDataSourceDirective extends OctoGraphQlDataSource {
7315
7395
  return new FetchResultTyped(transformedItems, totalCount);
7316
7396
  }));
7317
7397
  }
7318
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeEntitiesDataSourceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
7319
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: CkTypeEntitiesDataSourceDirective, isStandalone: true, selector: "[mmCkTypeEntitiesDataSource]", providers: [
7398
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeEntitiesDataSourceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
7399
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: CkTypeEntitiesDataSourceDirective, isStandalone: true, selector: "[mmCkTypeEntitiesDataSource]", providers: [
7320
7400
  {
7321
7401
  provide: DataSourceBase,
7322
7402
  useExisting: forwardRef(() => CkTypeEntitiesDataSourceDirective),
7323
7403
  },
7324
7404
  ], exportAs: ["mmCkTypeEntitiesDataSource"], usesInheritance: true, ngImport: i0 });
7325
7405
  }
7326
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CkTypeEntitiesDataSourceDirective, decorators: [{
7406
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CkTypeEntitiesDataSourceDirective, decorators: [{
7327
7407
  type: Directive,
7328
7408
  args: [{
7329
7409
  selector: '[mmCkTypeEntitiesDataSource]',
@@ -7415,21 +7495,29 @@ class RuntimeBrowserStateService {
7415
7495
  */
7416
7496
  getItemId(item) {
7417
7497
  const itemData = item.item;
7418
- // Runtime entity
7498
+ // Runtime entity — has both rtId and ckTypeId as scalar strings
7419
7499
  if ('rtId' in itemData && 'ckTypeId' in itemData) {
7420
7500
  return `${String(itemData.ckTypeId)}@${String(itemData.rtId)}`;
7421
7501
  }
7422
- // CK Model
7502
+ // CK Model — id is CkModelIdDto (object with fullName)
7423
7503
  if ('id' in itemData &&
7424
7504
  !('rtId' in itemData) &&
7425
7505
  !('ckTypeId' in itemData)) {
7426
- return `ck-model:${String(itemData.id)}`;
7506
+ const modelId = itemData.id;
7507
+ const name = typeof modelId === 'object' && modelId !== null && 'fullName' in modelId
7508
+ ? modelId.fullName
7509
+ : String(modelId);
7510
+ return `ck-model:${name}`;
7427
7511
  }
7428
- // CK Type
7512
+ // CK Type — ckTypeId is CkTypeIdDto (object with fullName)
7429
7513
  if ('ckTypeId' in itemData &&
7430
7514
  !('rtId' in itemData) &&
7431
7515
  !('id' in itemData)) {
7432
- return `ck-type:${String(itemData.ckTypeId)}`;
7516
+ const typeId = itemData.ckTypeId;
7517
+ const name = typeof typeId === 'object' && typeId !== null && 'fullName' in typeId
7518
+ ? typeId.fullName
7519
+ : String(typeId);
7520
+ return `ck-type:${name}`;
7433
7521
  }
7434
7522
  // CK Models root
7435
7523
  if ('isCkModelsRoot' in itemData && itemData.isCkModelsRoot) {
@@ -7437,10 +7525,10 @@ class RuntimeBrowserStateService {
7437
7525
  }
7438
7526
  return item.text || 'unknown';
7439
7527
  }
7440
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7441
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserStateService, providedIn: 'root' });
7528
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7529
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserStateService, providedIn: 'root' });
7442
7530
  }
7443
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserStateService, decorators: [{
7531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserStateService, decorators: [{
7444
7532
  type: Injectable,
7445
7533
  args: [{
7446
7534
  providedIn: 'root',
@@ -7462,10 +7550,10 @@ class TypeHelperService {
7462
7550
  && item.rtId
7463
7551
  && item.ckTypeId);
7464
7552
  }
7465
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TypeHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7466
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TypeHelperService, providedIn: 'root' });
7553
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TypeHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7554
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TypeHelperService, providedIn: 'root' });
7467
7555
  }
7468
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TypeHelperService, decorators: [{
7556
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TypeHelperService, decorators: [{
7469
7557
  type: Injectable,
7470
7558
  args: [{
7471
7559
  providedIn: 'root',
@@ -7488,10 +7576,10 @@ class CreateEntitiesDtoGQL extends i1$2.Mutation {
7488
7576
  constructor(apollo) {
7489
7577
  super(apollo);
7490
7578
  }
7491
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CreateEntitiesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7492
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CreateEntitiesDtoGQL, providedIn: 'root' });
7579
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CreateEntitiesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7580
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CreateEntitiesDtoGQL, providedIn: 'root' });
7493
7581
  }
7494
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CreateEntitiesDtoGQL, decorators: [{
7582
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CreateEntitiesDtoGQL, decorators: [{
7495
7583
  type: Injectable,
7496
7584
  args: [{
7497
7585
  providedIn: 'root'
@@ -7523,10 +7611,10 @@ class AttributeCoordinatorService {
7523
7611
  markStructureAsReady() {
7524
7612
  this.structureReady.set(true);
7525
7613
  }
7526
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeCoordinatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7527
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeCoordinatorService, providedIn: "root" });
7614
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeCoordinatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7615
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeCoordinatorService, providedIn: "root" });
7528
7616
  }
7529
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeCoordinatorService, decorators: [{
7617
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeCoordinatorService, decorators: [{
7530
7618
  type: Injectable,
7531
7619
  args: [{ providedIn: "root" }]
7532
7620
  }] });
@@ -7577,10 +7665,10 @@ class GetCkAttributesDetailedDtoGQL extends i1$2.Query {
7577
7665
  constructor(apollo) {
7578
7666
  super(apollo);
7579
7667
  }
7580
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkAttributesDetailedDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7581
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkAttributesDetailedDtoGQL, providedIn: 'root' });
7668
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkAttributesDetailedDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7669
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkAttributesDetailedDtoGQL, providedIn: 'root' });
7582
7670
  }
7583
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkAttributesDetailedDtoGQL, decorators: [{
7671
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkAttributesDetailedDtoGQL, decorators: [{
7584
7672
  type: Injectable,
7585
7673
  args: [{
7586
7674
  providedIn: 'root'
@@ -7634,16 +7722,71 @@ class GetCkRecordDetailedDtoGQL extends i1$2.Query {
7634
7722
  constructor(apollo) {
7635
7723
  super(apollo);
7636
7724
  }
7637
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkRecordDetailedDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7638
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkRecordDetailedDtoGQL, providedIn: 'root' });
7725
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkRecordDetailedDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
7726
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkRecordDetailedDtoGQL, providedIn: 'root' });
7639
7727
  }
7640
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkRecordDetailedDtoGQL, decorators: [{
7728
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkRecordDetailedDtoGQL, decorators: [{
7641
7729
  type: Injectable,
7642
7730
  args: [{
7643
7731
  providedIn: 'root'
7644
7732
  }]
7645
7733
  }], ctorParameters: () => [{ type: i1$2.Apollo }] });
7646
7734
 
7735
+ /**
7736
+ * Resolves raw CK attribute definitions for a CK type or CK record by id.
7737
+ *
7738
+ * Extracted from AttributeDataService to break a potential circular dependency:
7739
+ * AttributeMapperService needs to look up nested record attribute definitions when mapping
7740
+ * RECORD / RECORD_ARRAY values to GraphQL, while AttributeDataService already depends on
7741
+ * AttributeMapperService for mapping raw definitions into form-ready Attribute shapes.
7742
+ *
7743
+ * This resolver is intentionally minimal: it fetches and returns raw CkAttributeMetadata[]
7744
+ * with no mapping. Callers that need form-ready Attribute objects should map them via
7745
+ * AttributeMapperService.mapToFormAttribute.
7746
+ *
7747
+ * Apollo's default cache-first fetchPolicy deduplicates repeated lookups for the same ckId,
7748
+ * so callers do not need to memoize externally.
7749
+ */
7750
+ class AttributeMetadataResolverService {
7751
+ getCkAttributesDetailedGQL = inject(GetCkAttributesDetailedDtoGQL);
7752
+ getCkRecordDetailedGQL = inject(GetCkRecordDetailedDtoGQL);
7753
+ /**
7754
+ * Fetches raw attribute metadata for a CK type or CK record.
7755
+ * Returns an empty array when the id is missing or the request fails.
7756
+ */
7757
+ getRawAttributes$(ckId, isRecord = false) {
7758
+ if (!ckId)
7759
+ return of([]);
7760
+ const stream$ = isRecord
7761
+ ? this.fetchCkRecordAttributes(ckId)
7762
+ : this.fetchCkAttributes(ckId);
7763
+ return stream$.pipe(catchError$1((err) => {
7764
+ console.error('AttributeMetadataResolverService error:', err);
7765
+ return of([]);
7766
+ }));
7767
+ }
7768
+ fetchCkAttributes(ckTypeId) {
7769
+ return this.getCkAttributesDetailedGQL
7770
+ .fetch({ variables: { ckId: ckTypeId } })
7771
+ .pipe(map$1((res) => (res.data?.constructionKit?.types?.items?.[0]?.attributes?.items ??
7772
+ []).filter((item) => item != null)));
7773
+ }
7774
+ fetchCkRecordAttributes(ckRecordId) {
7775
+ return this.getCkRecordDetailedGQL
7776
+ .fetch({ variables: { ckId: ckRecordId } })
7777
+ .pipe(map$1((res) => (res.data?.constructionKit?.records?.items?.[0]?.attributes
7778
+ ?.items ?? []).filter((item) => item != null)));
7779
+ }
7780
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeMetadataResolverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7781
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeMetadataResolverService, providedIn: 'root' });
7782
+ }
7783
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeMetadataResolverService, decorators: [{
7784
+ type: Injectable,
7785
+ args: [{
7786
+ providedIn: 'root',
7787
+ }]
7788
+ }] });
7789
+
7647
7790
  class AttributeRecognitionService {
7648
7791
  isString(attributeValueType) {
7649
7792
  return attributeValueType === "STRING";
@@ -7685,10 +7828,10 @@ class AttributeRecognitionService {
7685
7828
  isStringArray(attributeValueType) {
7686
7829
  return attributeValueType === "STRING_ARRAY";
7687
7830
  }
7688
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeRecognitionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7689
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeRecognitionService, providedIn: "root" });
7831
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeRecognitionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
7832
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeRecognitionService, providedIn: "root" });
7690
7833
  }
7691
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeRecognitionService, decorators: [{
7834
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeRecognitionService, decorators: [{
7692
7835
  type: Injectable,
7693
7836
  args: [{ providedIn: "root" }]
7694
7837
  }] });
@@ -7759,6 +7902,7 @@ const BINARY_REFERENCE_FLAG = "__isBinaryFromBase64";
7759
7902
  */
7760
7903
  class AttributeMapperService {
7761
7904
  recognition = inject(AttributeRecognitionService);
7905
+ metadataResolver = inject(AttributeMetadataResolverService);
7762
7906
  isRecordValue(value) {
7763
7907
  return typeof value === "object" && value !== null && !Array.isArray(value);
7764
7908
  }
@@ -7814,115 +7958,187 @@ class AttributeMapperService {
7814
7958
  return defer(() => from(this.mapFormValueToGraphQLAttributes(formValue, attributesMetadata)));
7815
7959
  }
7816
7960
  /**
7817
- * Maps form values to GraphQL format for createEntities / updateRuntimeEntities.
7818
- * Record and RecordArray are passed as nested objects/arrays. BINARY_LINKED is included only when value is a File.
7961
+ * Maps form values to GraphQL format for createEntities / updateRuntimeEntities. Top-level RECORD and
7962
+ * RECORD_ARRAY attribute values are recursively mapped via the same per-attribute logic so nested
7963
+ * scalars (BINARY, GEO, TIME_SPAN, …) get type conversion identical to their top-level siblings.
7819
7964
  */
7820
7965
  async mapFormValueToGraphQLAttributes(formValue, attributesMetadata) {
7821
- const result = [];
7822
7966
  if (!this.isRecordValue(formValue)) {
7823
- return result;
7824
- }
7825
- const metadataMap = new Map();
7826
- if (attributesMetadata) {
7827
- attributesMetadata.forEach((attr) => {
7828
- metadataMap.set(attr.attributeName, attr);
7829
- });
7967
+ return [];
7830
7968
  }
7969
+ const metadataMap = new Map((attributesMetadata ?? []).map((attr) => [attr.attributeName, attr]));
7970
+ const result = [];
7831
7971
  for (const [key, value] of Object.entries(formValue)) {
7832
- if (!key) {
7833
- continue;
7834
- }
7835
- const metadata = metadataMap.get(key);
7836
- if (metadata?.attributeValueType === "BINARY_LINKED") {
7837
- const processedValue = await this.processAttributeValue(value, metadata?.attributeValueType);
7838
- if (processedValue instanceof File) {
7839
- // Skip synthetic reference/preview files — they are placeholders created by
7840
- // parseBinaryLinkedForForm and must not be re-uploaded (would overwrite real data with zeros).
7841
- if (processedValue[BINARY_LINKED_REFERENCE_FLAG]) {
7842
- continue;
7843
- }
7844
- result.push({ attributeName: key, value: processedValue });
7845
- }
7846
- else {
7847
- // Value was cleared (null / empty array) — send null so the backend removes the linked binary.
7848
- result.push({ attributeName: key, value: null });
7849
- }
7972
+ if (!key)
7850
7973
  continue;
7974
+ const mapped = await this.mapSingleAttributeToInput(key, value, metadataMap.get(key));
7975
+ if (mapped !== null) {
7976
+ result.push(mapped);
7851
7977
  }
7852
- if (value === null || value === undefined) {
7853
- if (metadata?.isOptional) {
7854
- result.push({ attributeName: key, value: null });
7855
- }
7856
- continue;
7978
+ }
7979
+ return result;
7980
+ }
7981
+ /**
7982
+ * Maps a single (key, value, metadata) triple into a GraphQL RtEntityAttributeInput, or null when the
7983
+ * attribute should be omitted from the payload entirely (typically: required scalar with no value).
7984
+ *
7985
+ * Single source of truth for empty / null / optional / type-conversion rules. Used by both the top-level
7986
+ * mapping and the recursive RECORD / RECORD_ARRAY mapping so nested attributes follow the exact same
7987
+ * contract. Branch order matters: BINARY_LINKED handling must come before the generic null/undefined
7988
+ * skip because cleared linked binaries are sent as explicit null (to detach the link on the backend).
7989
+ */
7990
+ async mapSingleAttributeToInput(key, value, metadata) {
7991
+ const type = metadata?.attributeValueType;
7992
+ // type is set only when metadata exists, so the non-null assertion is safe inside these branches.
7993
+ if (type === "BINARY_LINKED") {
7994
+ return this.mapBinaryLinkedAttribute(key, value, metadata);
7995
+ }
7996
+ if (value === null || value === undefined) {
7997
+ return metadata?.isOptional ? { attributeName: key, value: null } : null;
7998
+ }
7999
+ if (type === "BINARY" && this.isOptionalEmptyBinary(metadata, value)) {
8000
+ return { attributeName: key, value: null };
8001
+ }
8002
+ // Empty RECORD (empty object) and RECORD_ARRAY (empty array): send null when optional, skip otherwise.
8003
+ if (type === "RECORD" && this.isValueEmpty(value)) {
8004
+ return metadata?.isOptional ? { attributeName: key, value: null } : null;
8005
+ }
8006
+ if (type === "RECORD_ARRAY" && Array.isArray(value) && value.length === 0) {
8007
+ return metadata?.isOptional ? { attributeName: key, value: null } : null;
8008
+ }
8009
+ if (metadata?.isOptional &&
8010
+ this.isOptionalEmptyScalarOrArray(value, metadata)) {
8011
+ return { attributeName: key, value: null };
8012
+ }
8013
+ const processedValue = await this.processAttributeValue(value, metadata);
8014
+ return { attributeName: key, value: processedValue };
8015
+ }
8016
+ /**
8017
+ * BINARY_LINKED has its own decision tree because synthetic reference Files (created by
8018
+ * parseBinaryLinkedForForm to display existing-file metadata) must NOT be re-uploaded — re-uploading
8019
+ * a synthetic File would overwrite the real binary with zero-filled placeholder content.
8020
+ * Cleared values (null / empty array) emit explicit null so the backend detaches the linked binary.
8021
+ */
8022
+ async mapBinaryLinkedAttribute(key, value, metadata) {
8023
+ const processedValue = await this.processAttributeValue(value, metadata);
8024
+ if (processedValue instanceof File) {
8025
+ const isReference = processedValue[BINARY_LINKED_REFERENCE_FLAG] === true;
8026
+ if (isReference) {
8027
+ return null;
7857
8028
  }
7858
- if (metadata?.attributeValueType === "BINARY" &&
7859
- this.isOptionalEmptyBinary(metadata, value)) {
7860
- result.push({ attributeName: key, value: null });
8029
+ return { attributeName: key, value: processedValue };
8030
+ }
8031
+ return { attributeName: key, value: null };
8032
+ }
8033
+ /**
8034
+ * Recursively maps a RECORD form value (flat object { subAttr: subVal, ... }) to the wire shape expected
8035
+ * by the backend mutation: a flat object { subAttr: processedSubVal, ... }.
8036
+ *
8037
+ * Important asymmetry between query response and mutation input: queries return RECORD as
8038
+ * { attributes: [{ attributeName, value }, ...] } (the GraphQL RtRecord type wraps it), but the mutation
8039
+ * input field RtEntityAttributeInput.value is SimpleScalar — opaque to GraphQL — so the backend reads
8040
+ * the raw dictionary directly and matches keys against CK sub-attribute names. Sending the wrapped
8041
+ * { attributes: [...] } shape resulted in ASSET1004 (mandatory attribute missing) because the backend
8042
+ * never iterated the wrapper.
8043
+ *
8044
+ * Fetches sub-attribute definitions for the given recordCkId via AttributeMetadataResolverService and
8045
+ * routes each entry through mapSingleAttributeToInput so type conversion (BINARY → byte[], GEO → GeoJSON,
8046
+ * TIME_SPAN → seconds, …) and empty/null/optional rules apply identically to nested attributes.
8047
+ * Sub-attribute keys are kept in their form-side camelCase form (matches the previously working code path).
8048
+ */
8049
+ async mapRecordValueToGraphQL(value, recordCkId) {
8050
+ if (!this.isRecordValue(value)) {
8051
+ return {};
8052
+ }
8053
+ const subMetadataMap = await this.resolveSubMetadataMap(recordCkId);
8054
+ return this.mapRecordEntries(value, subMetadataMap);
8055
+ }
8056
+ /**
8057
+ * Resolves sub-attribute metadata for a given recordCkId. Returns an empty map (pass-through mode)
8058
+ * when recordCkId is missing or resolver fails — caller must preserve user values in that case.
8059
+ */
8060
+ async resolveSubMetadataMap(recordCkId) {
8061
+ if (!recordCkId) {
8062
+ return new Map();
8063
+ }
8064
+ try {
8065
+ const rawDefinitions = await firstValueFrom(this.metadataResolver.getRawAttributes$(recordCkId, true));
8066
+ return new Map(rawDefinitions.map((meta) => {
8067
+ const subAttr = this.mapToFormAttribute(meta, undefined);
8068
+ return [subAttr.attributeName, subAttr];
8069
+ }));
8070
+ }
8071
+ catch (err) {
8072
+ // Resolver failure (network/auth/cache) must not abort the whole mapping pipeline. Falling back
8073
+ // to an empty map means sub-attributes are emitted with their form values without type conversion;
8074
+ // the backend will reject the payload with a meaningful error rather than the user seeing nothing.
8075
+ console.error(`AttributeMapperService: failed to resolve sub-attributes for record '${recordCkId}'`, err);
8076
+ return new Map();
8077
+ }
8078
+ }
8079
+ /**
8080
+ * Maps record entries to GraphQL payload using the resolved metadata map.
8081
+ * Pass-through mode (empty metadata map) preserves user values verbatim, including explicit
8082
+ * nulls — required so cleared nested fields still reach the backend.
8083
+ */
8084
+ async mapRecordEntries(value, subMetadataMap) {
8085
+ const result = {};
8086
+ for (const [subKey, subValue] of Object.entries(value)) {
8087
+ if (!subKey)
7861
8088
  continue;
7862
- }
7863
- // Skip empty RECORD (empty object) and RECORD_ARRAY (empty array) unless optional (then send null)
7864
- if (metadata?.attributeValueType === "RECORD" &&
7865
- this.isValueEmpty(value)) {
7866
- if (metadata?.isOptional) {
7867
- result.push({ attributeName: key, value: null });
7868
- }
8089
+ const subMeta = subMetadataMap.get(subKey);
8090
+ if (!subMeta) {
8091
+ // Pass-through: no metadata available, preserve the value as-is (including nulls).
8092
+ result[subKey] = subValue;
7869
8093
  continue;
7870
8094
  }
7871
- if (metadata?.attributeValueType === "RECORD_ARRAY" &&
7872
- Array.isArray(value) &&
7873
- value.length === 0) {
7874
- if (metadata?.isOptional) {
7875
- result.push({ attributeName: key, value: null });
7876
- }
7877
- continue;
8095
+ const mapped = await this.mapSingleAttributeToInput(subKey, subValue, subMeta);
8096
+ if (mapped !== null) {
8097
+ result[mapped.attributeName] = mapped.value;
7878
8098
  }
7879
- if (metadata?.isOptional && this.isOptionalEmptyScalarOrArray(value, metadata)) {
7880
- result.push({ attributeName: key, value: null });
8099
+ }
8100
+ return result;
8101
+ }
8102
+ /**
8103
+ * Recursively maps a RECORD_ARRAY form value (array of flat objects) to the wire shape expected by the
8104
+ * backend mutation: an array of flat objects [{ subAttr: subVal }, { subAttr: subVal }].
8105
+ *
8106
+ * Each item is a record sharing the same recordCkId; metadata is fetched (and Apollo-cached) once per item
8107
+ * via mapRecordValueToGraphQL.
8108
+ */
8109
+ async mapRecordArrayValueToGraphQL(value, recordCkId) {
8110
+ if (!Array.isArray(value))
8111
+ return [];
8112
+ // Resolve metadata once for the whole array — items share the same recordCkId.
8113
+ const subMetadataMap = await this.resolveSubMetadataMap(recordCkId);
8114
+ const result = [];
8115
+ for (const item of value) {
8116
+ if (!this.isRecordValue(item)) {
8117
+ result.push({});
7881
8118
  continue;
7882
8119
  }
7883
- const processedValue = await this.processAttributeValue(value, metadata?.attributeValueType);
7884
- result.push({
7885
- attributeName: key,
7886
- value: processedValue,
7887
- });
8120
+ result.push(await this.mapRecordEntries(item, subMetadataMap));
7888
8121
  }
7889
8122
  return result;
7890
8123
  }
7891
8124
  /** Processes a single attribute value for mutation payload (type-specific conversion). */
7892
- async processAttributeValue(value, attributeType) {
8125
+ async processAttributeValue(value, metadata) {
8126
+ const attributeType = metadata?.attributeValueType;
7893
8127
  switch (attributeType) {
7894
8128
  case "RECORD":
7895
- return value;
8129
+ return await this.mapRecordValueToGraphQL(value, metadata?.id?.ckId);
7896
8130
  case "RECORD_ARRAY":
7897
- return value;
8131
+ return await this.mapRecordArrayValueToGraphQL(value, metadata?.id?.ckId);
7898
8132
  case "GEOSPATIAL_POINT":
7899
8133
  return convertGeospatialPointToGeoJSON(value);
7900
8134
  case "TIME_SPAN":
7901
8135
  return this.convertTimeSpanToSeconds(value);
7902
- case "BINARY": {
8136
+ case "BINARY":
7903
8137
  // MeshMakers expects byte[] (array of numbers). Accept File, ArrayBuffer, base64 string, or byte[].
7904
8138
  return await this.convertBinaryToByteArray(value);
7905
- }
7906
- case "BINARY_LINKED": {
7907
- // MeshMakers: prefer File for multipart, but also accept base64 or byte[]
7908
- if (value instanceof File) {
7909
- return value;
7910
- }
7911
- if (Array.isArray(value) && value[0] instanceof File) {
7912
- return value[0];
7913
- }
7914
- if (typeof value === "string") {
7915
- // base64 string
7916
- return base64ToByteArray(value);
7917
- }
7918
- if (value instanceof ArrayBuffer) {
7919
- return this.arrayBufferToByteArray(value);
7920
- }
7921
- if (Array.isArray(value) && typeof value[0] === "number") {
7922
- return value;
7923
- }
7924
- return null;
7925
- }
8139
+ case "BINARY_LINKED":
8140
+ // MeshMakers: prefer File for multipart upload; also accept base64 string, ArrayBuffer or byte[].
8141
+ return this.convertBinaryLinkedValue(value);
7926
8142
  case "INTEGER_ARRAY":
7927
8143
  return this.normalizePrimitiveArray(value, "number");
7928
8144
  case "STRING_ARRAY":
@@ -8028,7 +8244,8 @@ class AttributeMapperService {
8028
8244
  }
8029
8245
  }
8030
8246
  /**
8031
- * Converts supported binary representations into byte arrays.
8247
+ * Converts supported binary representations into byte arrays. Returns the original value as a fallback
8248
+ * when the input shape is not recognized so the backend can produce a meaningful validation error.
8032
8249
  */
8033
8250
  async convertBinaryToByteArray(value) {
8034
8251
  if (Array.isArray(value) &&
@@ -8056,6 +8273,36 @@ class AttributeMapperService {
8056
8273
  }
8057
8274
  return value;
8058
8275
  }
8276
+ /**
8277
+ * Normalizes a BINARY_LINKED form value to one of the wire shapes the backend accepts. Order matters:
8278
+ * a real File is preferred (multipart upload preserves filename and content type), with byte[] / base64
8279
+ * accepted as fallbacks for callers that already have raw bytes.
8280
+ */
8281
+ convertBinaryLinkedValue(value) {
8282
+ if (value instanceof File)
8283
+ return value;
8284
+ if (Array.isArray(value) && value[0] instanceof File)
8285
+ return value[0];
8286
+ if (typeof value === "string") {
8287
+ try {
8288
+ return base64ToByteArray(value);
8289
+ }
8290
+ catch (e) {
8291
+ // Re-throw instead of returning null: a malformed base64 must not silently degrade
8292
+ // to null, which the backend may interpret as "clear/detach" the linked binary.
8293
+ // Surfacing the error lets the caller present a validation message to the user.
8294
+ console.error("Error converting BINARY_LINKED base64 to byte array:", e);
8295
+ throw new Error("Invalid base64 value for BINARY_LINKED attribute", { cause: e });
8296
+ }
8297
+ }
8298
+ if (value instanceof ArrayBuffer) {
8299
+ return this.arrayBufferToByteArray(value);
8300
+ }
8301
+ if (Array.isArray(value) && typeof value[0] === "number") {
8302
+ return value;
8303
+ }
8304
+ return null;
8305
+ }
8059
8306
  // ─── Type recognition (single responsibility: attribute type checks) ─────────────
8060
8307
  isEnum(attr) {
8061
8308
  return attr.attributeValueType === "ENUM";
@@ -8427,10 +8674,10 @@ class AttributeMapperService {
8427
8674
  }
8428
8675
  return [];
8429
8676
  }
8430
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeMapperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8431
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeMapperService, providedIn: "root" });
8677
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeMapperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8678
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeMapperService, providedIn: "root" });
8432
8679
  }
8433
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeMapperService, decorators: [{
8680
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeMapperService, decorators: [{
8434
8681
  type: Injectable,
8435
8682
  args: [{
8436
8683
  providedIn: "root",
@@ -8438,25 +8685,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
8438
8685
  }] });
8439
8686
 
8440
8687
  /**
8441
- * Single responsibility: fetch attribute definitions (CK types/records) and runtime entity values for the repository browser.
8688
+ * Fetches form-ready attribute definitions and runtime entity values for the repository browser.
8442
8689
  * Used by attributes-group (rxResource), create-editor and update-editor (firstValueFrom for mutations).
8690
+ *
8691
+ * Raw definition lookups are delegated to AttributeMetadataResolverService; this service
8692
+ * only adds the form-ready mapping (mapToFormAttribute) and required-first sort.
8443
8693
  */
8444
8694
  class AttributeDataService {
8445
8695
  mapper = inject(AttributeMapperService);
8446
- getCkAttributesDetailedGQL = inject(GetCkAttributesDetailedDtoGQL);
8447
- getCkRecordDetailedGQL = inject(GetCkRecordDetailedDtoGQL);
8696
+ resolver = inject(AttributeMetadataResolverService);
8448
8697
  getRtEntityAttributesGQL = inject(GetRuntimeEntityByIdDtoGQL);
8449
8698
  /** Observable of attribute list for a CK type or record. Sorted: required first, optional last. */
8450
8699
  getAttributesDefinition$(ckTypeId, isRecord = false) {
8451
8700
  if (!ckTypeId)
8452
8701
  return of([]);
8453
- const stream$ = isRecord
8454
- ? this.fetchCkRecordAttributes(ckTypeId)
8455
- : this.fetchCkAttributes(ckTypeId);
8456
- return stream$.pipe(map$1((items) => this.sortAttributesByOptional(items.map((meta) => this.mapper.mapToFormAttribute(meta, undefined)))), catchError$1((err) => {
8457
- console.error('Service error:', err);
8458
- return of([]);
8459
- }));
8702
+ return this.resolver.getRawAttributes$(ckTypeId, isRecord).pipe(map$1((items) => this.sortAttributesByOptional(items.map((meta) => this.mapper.mapToFormAttribute(meta, undefined)))));
8460
8703
  }
8461
8704
  /** Observable of initial attribute values for an existing entity (edit mode). */
8462
8705
  getRtEntityValues$(rtId, ckTypeId) {
@@ -8474,18 +8717,6 @@ class AttributeDataService {
8474
8717
  return a.isOptional ? 1 : -1;
8475
8718
  });
8476
8719
  }
8477
- fetchCkAttributes(ckTypeId) {
8478
- return this.getCkAttributesDetailedGQL
8479
- .fetch({ variables: { ckId: ckTypeId } })
8480
- .pipe(map$1((res) => (res.data?.constructionKit?.types?.items?.[0]?.attributes?.items ??
8481
- []).filter((item) => item != null)));
8482
- }
8483
- fetchCkRecordAttributes(ckRecordId) {
8484
- return this.getCkRecordDetailedGQL
8485
- .fetch({ variables: { ckId: ckRecordId } })
8486
- .pipe(map$1((res) => (res.data?.constructionKit?.records?.items?.[0]?.attributes
8487
- ?.items ?? []).filter((item) => item != null)));
8488
- }
8489
8720
  /** Fetches runtime entity attribute items by rtId and ckTypeId; returns empty array when absent. */
8490
8721
  fetchRtEntityAttributes(rtId, ckTypeId) {
8491
8722
  return this.getRtEntityAttributesGQL
@@ -8501,10 +8732,10 @@ class AttributeDataService {
8501
8732
  }));
8502
8733
  }));
8503
8734
  }
8504
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8505
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeDataService, providedIn: 'root' });
8735
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8736
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeDataService, providedIn: 'root' });
8506
8737
  }
8507
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeDataService, decorators: [{
8738
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeDataService, decorators: [{
8508
8739
  type: Injectable,
8509
8740
  args: [{
8510
8741
  providedIn: 'root',
@@ -8548,8 +8779,8 @@ class AttributeFieldComponent {
8548
8779
  hasHint() {
8549
8780
  return this.hintText() != null && this.hintText() !== "";
8550
8781
  }
8551
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8552
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AttributeFieldComponent, isStandalone: true, selector: "mm-attribute-field", inputs: { attribute: { classPropertyName: "attribute", publicName: "attribute", isSignal: true, isRequired: true, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: true, transformFunction: null }, baselineValue: { classPropertyName: "baselineValue", publicName: "baselineValue", isSignal: true, isRequired: false, transformFunction: null }, fieldId: { classPropertyName: "fieldId", publicName: "fieldId", isSignal: true, isRequired: false, transformFunction: null }, overrideLabelText: { classPropertyName: "overrideLabelText", publicName: "overrideLabelText", isSignal: true, isRequired: false, transformFunction: null }, showUndoButton: { classPropertyName: "showUndoButton", publicName: "showUndoButton", isSignal: true, isRequired: false, transformFunction: null }, undoButtonSize: { classPropertyName: "undoButtonSize", publicName: "undoButtonSize", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, hintText: { classPropertyName: "hintText", publicName: "hintText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { undo: "undo" }, ngImport: i0, template: `
8782
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8783
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: AttributeFieldComponent, isStandalone: true, selector: "mm-attribute-field", inputs: { attribute: { classPropertyName: "attribute", publicName: "attribute", isSignal: true, isRequired: true, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: true, transformFunction: null }, baselineValue: { classPropertyName: "baselineValue", publicName: "baselineValue", isSignal: true, isRequired: false, transformFunction: null }, fieldId: { classPropertyName: "fieldId", publicName: "fieldId", isSignal: true, isRequired: false, transformFunction: null }, overrideLabelText: { classPropertyName: "overrideLabelText", publicName: "overrideLabelText", isSignal: true, isRequired: false, transformFunction: null }, showUndoButton: { classPropertyName: "showUndoButton", publicName: "showUndoButton", isSignal: true, isRequired: false, transformFunction: null }, undoButtonSize: { classPropertyName: "undoButtonSize", publicName: "undoButtonSize", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, hintText: { classPropertyName: "hintText", publicName: "hintText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { undo: "undo" }, ngImport: i0, template: `
8553
8784
  <div class="k-form-field">
8554
8785
  <kendo-label
8555
8786
  [for]="fieldId()"
@@ -8586,7 +8817,7 @@ class AttributeFieldComponent {
8586
8817
  </div>
8587
8818
  `, isInline: true, styles: [".k-form-field{display:flex;flex-direction:column;gap:4px;margin-bottom:12px}.field-input-container{display:flex;flex-direction:row;align-items:center;gap:8px}.field-input-container .input-wrapper{flex:1;min-width:0}.field-input-container .input-wrapper ::ng-deep .k-widget,.field-input-container .input-wrapper ::ng-deep .k-textbox,.field-input-container .input-wrapper ::ng-deep .k-numerictextbox,.field-input-container .input-wrapper ::ng-deep .k-dropdownlist{width:100%}.k-form-error{font-size:.75rem;margin-top:4px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: i1$4.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "component", type: i3$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
8588
8819
  }
8589
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributeFieldComponent, decorators: [{
8820
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributeFieldComponent, decorators: [{
8590
8821
  type: Component,
8591
8822
  args: [{ selector: "mm-attribute-field", standalone: true, imports: [CommonModule, ReactiveFormsModule, KENDO_LABEL, KENDO_BUTTONS], template: `
8592
8823
  <div class="k-form-field">
@@ -8945,8 +9176,8 @@ class AttributesGroupComponent {
8945
9176
  }
8946
9177
  return EMPTY_INITIAL_VALUES;
8947
9178
  }
8948
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributesGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8949
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AttributesGroupComponent, isStandalone: true, selector: "mm-attributes-group", inputs: { ckId: { classPropertyName: "ckId", publicName: "ckId", isSignal: true, isRequired: true, transformFunction: null }, parentFormGroup: { classPropertyName: "parentFormGroup", publicName: "parentFormGroup", isSignal: true, isRequired: true, transformFunction: null }, isRecord: { classPropertyName: "isRecord", publicName: "isRecord", isSignal: true, isRequired: false, transformFunction: null }, initialValues: { classPropertyName: "initialValues", publicName: "initialValues", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
9179
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributesGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9180
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: AttributesGroupComponent, isStandalone: true, selector: "mm-attributes-group", inputs: { ckId: { classPropertyName: "ckId", publicName: "ckId", isSignal: true, isRequired: true, transformFunction: null }, parentFormGroup: { classPropertyName: "parentFormGroup", publicName: "parentFormGroup", isSignal: true, isRequired: true, transformFunction: null }, isRecord: { classPropertyName: "isRecord", publicName: "isRecord", isSignal: true, isRequired: false, transformFunction: null }, initialValues: { classPropertyName: "initialValues", publicName: "initialValues", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8950
9181
  <div class="attributes-form-container" [formGroup]="parentFormGroup()">
8951
9182
  <kendo-card [style.margin-bottom.px]="10">
8952
9183
  <kendo-card-header>
@@ -9233,7 +9464,7 @@ class AttributesGroupComponent {
9233
9464
  </div>
9234
9465
  `, isInline: true, styles: [".attributes-form-container ::ng-deep kendo-card kendo-card-body{display:flex;flex-direction:column;gap:16px}.attributes-form-container ::ng-deep kendo-label{display:flex;flex-direction:column;gap:4px}.attributes-form-container ::ng-deep kendo-label label{text-transform:uppercase}.header-content{display:flex;flex-direction:column;gap:4px}.record-array-content,.tab-content-wrapper{display:flex;flex-direction:column;gap:16px}.record-actions-info{display:flex;flex-direction:column;gap:12px;padding:16px;background-color:var(--kendo-color-surface-alt, rgba(0, 0, 0, .05));border:1px solid var(--kendo-color-border, rgba(0, 0, 0, .1));border-radius:4px;margin-bottom:16px}.record-actions-description{margin:0;font-size:13px;color:var(--kendo-color-subtle, rgba(0, 0, 0, .6));line-height:1.5}.record-array-actions{display:flex;gap:8px;justify-content:flex-start;padding-top:0}.record-actions{margin-top:16px;display:flex;gap:8px;justify-content:flex-start;padding-top:0}.binary-linked-wrap{display:flex;flex-direction:column;gap:6px}.binary-linked-reference-hint{font-size:.75rem;color:var(--kendo-color-primary, #0f6dff);font-style:italic}\n"], dependencies: [{ kind: "component", type: i0.forwardRef(() => AttributesGroupComponent), selector: "mm-attributes-group", inputs: ["ckId", "parentFormGroup", "isRecord", "initialValues"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i1.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i1.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i1.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i0.forwardRef(() => i1.FormGroupName), selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: i0.forwardRef(() => i1$3.CardComponent), selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i0.forwardRef(() => i1$3.CardBodyComponent), selector: "kendo-card-body" }, { kind: "component", type: i0.forwardRef(() => i1$3.CardHeaderComponent), selector: "kendo-card-header" }, { kind: "component", type: i0.forwardRef(() => i1$3.ExpansionPanelComponent), selector: "kendo-expansionpanel", inputs: ["title", "subtitle", "disabled", "expanded", "svgExpandIcon", "svgCollapseIcon", "expandIcon", "collapseIcon", "animation"], outputs: ["expandedChange", "action", "expand", "collapse"], exportAs: ["kendoExpansionPanel"] }, { kind: "directive", type: i0.forwardRef(() => i1$3.ExpansionPanelTitleDirective), selector: "[kendoExpansionPanelTitleDirective]" }, { kind: "component", type: i0.forwardRef(() => i1$3.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: i0.forwardRef(() => i1$3.TabStripTabComponent), selector: "kendo-tabstrip-tab", inputs: ["title", "disabled", "cssClass", "cssStyle", "selected", "closable", "closeIcon", "closeIconClass", "closeSVGIcon"], exportAs: ["kendoTabStripTab"] }, { kind: "directive", type: i0.forwardRef(() => i1$3.TabContentDirective), selector: "[kendoTabContent]" }, { kind: "component", type: i0.forwardRef(() => i5.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: i0.forwardRef(() => i5.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: i0.forwardRef(() => i5.SwitchComponent), selector: "kendo-switch", inputs: ["focusableId", "onLabel", "offLabel", "checked", "disabled", "readonly", "tabindex", "size", "thumbRounded", "trackRounded", "tabIndex"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoSwitch"] }, { kind: "component", type: i0.forwardRef(() => i1$4.LabelComponent), selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }, { kind: "component", type: i0.forwardRef(() => i3$1.ButtonComponent), selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: i0.forwardRef(() => 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: i0.forwardRef(() => 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: i0.forwardRef(() => i7.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: "component", type: i0.forwardRef(() => i7.TimePickerComponent), selector: "kendo-timepicker", inputs: ["focusableId", "disabled", "readonly", "readOnlyInput", "clearButton", "format", "formatPlaceholder", "placeholder", "min", "max", "incompleteDateValidation", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "cancelButton", "nowButton", "steps", "popupSettings", "tabindex", "tabIndex", "adaptiveTitle", "adaptiveSubtitle", "rangeValidation", "adaptiveMode", "value", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-timepicker"] }, { kind: "component", type: i0.forwardRef(() => i8.FileSelectComponent), selector: "kendo-fileselect", inputs: ["name"], outputs: ["valueChange"], exportAs: ["kendoFileSelect"] }, { kind: "component", type: i0.forwardRef(() => AttributeFieldComponent), selector: "mm-attribute-field", inputs: ["attribute", "control", "baselineValue", "fieldId", "overrideLabelText", "showUndoButton", "undoButtonSize", "errorMessage", "hintText"], outputs: ["undo"] }] });
9235
9466
  }
9236
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AttributesGroupComponent, decorators: [{
9467
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: AttributesGroupComponent, decorators: [{
9237
9468
  type: Component,
9238
9469
  args: [{ selector: "mm-attributes-group", standalone: true, imports: [
9239
9470
  CommonModule,
@@ -9538,50 +9769,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
9538
9769
  const EMPTY_INITIAL_VALUES = [];
9539
9770
 
9540
9771
  /**
9541
- * Shared utilities for create and update entity editors: mutation options (including multipart for binary uploads)
9542
- * and error notifications. Injected by both CreateEditorComponent and UpdateEditorComponent.
9772
+ * Shared utilities for create and update entity editors: builds Apollo mutation options (with multipart
9773
+ * context for binary uploads) and shows error notifications. Injected by both CreateEditorComponent and
9774
+ * UpdateEditorComponent.
9543
9775
  */
9544
9776
  class SharedEditor {
9545
9777
  notificationService = inject(NotificationService);
9546
9778
  /**
9547
- * Builds Apollo mutation options for createEntities: variables and optional multipart context when attributes contain File(s).
9779
+ * Builds Apollo mutation options for createEntities. Multipart context is enabled when any attribute
9780
+ * value (top-level or nested in RECORD / RECORD_ARRAY) contains a File instance.
9548
9781
  */
9549
9782
  prepareMutationOptions(entityInput) {
9550
- const mutationOptions = {
9551
- variables: { entities: [entityInput] },
9552
- };
9553
- // Use multipart for binary file uploads (BINARY_LINKED or BINARY)
9554
- const hasBinaryFiles = entityInput.attributes?.some((attr) => {
9555
- // BINARY_LINKED: File, BINARY: File or File[]
9556
- if (attr?.value instanceof File)
9557
- return true;
9558
- if (Array.isArray(attr?.value) && attr?.value[0] instanceof File)
9559
- return true;
9560
- return false;
9561
- }) ?? false;
9562
- if (hasBinaryFiles) {
9563
- mutationOptions.context = { useMultipart: true };
9564
- }
9565
- return mutationOptions;
9783
+ return this.buildMutationOptions({ entities: [entityInput] });
9566
9784
  }
9567
9785
  /**
9568
- * Builds Apollo mutation options for updateRuntimeEntities: variables and optional multipart context when attributes contain File(s).
9786
+ * Builds Apollo mutation options for updateRuntimeEntities. Multipart context is enabled when any
9787
+ * attribute value (top-level or nested in RECORD / RECORD_ARRAY) contains a File instance.
9569
9788
  */
9570
9789
  prepareUpdateMutationOptions(entities) {
9571
- const mutationOptions = {
9572
- variables: { entities },
9573
- };
9574
- const hasBinaryFiles = entities?.some((e) => e?.item?.attributes?.some((attr) => {
9575
- if (attr?.value instanceof File)
9576
- return true;
9577
- if (Array.isArray(attr?.value) && attr?.value[0] instanceof File)
9578
- return true;
9579
- return false;
9580
- })) ?? false;
9581
- if (hasBinaryFiles) {
9582
- mutationOptions.context = { useMultipart: true };
9583
- }
9584
- return mutationOptions;
9790
+ return this.buildMutationOptions({ entities });
9585
9791
  }
9586
9792
  /**
9587
9793
  * Shows an error notification to the user.
@@ -9595,10 +9801,36 @@ class SharedEditor {
9595
9801
  type: { style: "error", icon: true },
9596
9802
  });
9597
9803
  }
9598
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SharedEditor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
9599
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SharedEditor, providedIn: "root" });
9804
+ /** Wraps variables with optional multipart context based on whether a File is present anywhere in the payload. */
9805
+ buildMutationOptions(variables) {
9806
+ const options = { variables };
9807
+ if (this.containsFile(variables)) {
9808
+ options.context = { useMultipart: true };
9809
+ }
9810
+ return options;
9811
+ }
9812
+ /**
9813
+ * Recursively checks whether the given value contains a File instance anywhere in its structure
9814
+ * (top-level, inside arrays or inside nested objects). Used to decide whether the mutation must
9815
+ * be sent as a multipart request so that nested BINARY_LINKED files are uploaded correctly.
9816
+ */
9817
+ containsFile(value) {
9818
+ if (value == null)
9819
+ return false;
9820
+ if (value instanceof File)
9821
+ return true;
9822
+ if (Array.isArray(value)) {
9823
+ return value.some((item) => this.containsFile(item));
9824
+ }
9825
+ if (typeof value === "object") {
9826
+ return Object.values(value).some((v) => this.containsFile(v));
9827
+ }
9828
+ return false;
9829
+ }
9830
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SharedEditor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
9831
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SharedEditor, providedIn: "root" });
9600
9832
  }
9601
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SharedEditor, decorators: [{
9833
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: SharedEditor, decorators: [{
9602
9834
  type: Injectable,
9603
9835
  args: [{
9604
9836
  providedIn: "root",
@@ -9730,18 +9962,23 @@ class CreateEditorComponent {
9730
9962
  hasValidMappedAttributes(mapped) {
9731
9963
  return Array.isArray(mapped) && mapped.length > 0;
9732
9964
  }
9733
- /** Builds the create mutation payload: ckTypeId, attributes, optional parent association. */
9965
+ /**
9966
+ * Builds the create mutation payload: ckTypeId, attributes, and an optional parent association.
9967
+ * The association role defaults to "parent" (Basic/TreeNode convention) and can be overridden via
9968
+ * CreateInput.parentRoleName for CK Types that expose the parent link under a different role name.
9969
+ */
9734
9970
  buildCreatePayload(attributes) {
9735
9971
  const ckTypeId = this.selectedCkTypeId() ?? this.selectedRtCkTypeId();
9736
9972
  const entity = {
9737
9973
  ckTypeId: ckTypeId,
9738
9974
  attributes,
9739
9975
  };
9740
- const parent = this.createInput()?.parent;
9976
+ const input = this.createInput();
9977
+ const parent = input?.parent;
9741
9978
  if (parent?.ckTypeId && parent?.rtId) {
9742
9979
  entity.associations = [
9743
9980
  {
9744
- roleName: "parent",
9981
+ roleName: input?.parentRoleName ?? "parent",
9745
9982
  targets: [
9746
9983
  {
9747
9984
  modOption: AssociationModOptionsDto.CreateDto,
@@ -9778,8 +10015,8 @@ class CreateEditorComponent {
9778
10015
  this.selectedRtCkTypeId.set(null);
9779
10016
  this.selectedCkTypeId.set(null);
9780
10017
  }
9781
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CreateEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9782
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CreateEditorComponent, isStandalone: true, selector: "mm-create-editor-component", inputs: { createInput: { classPropertyName: "createInput", publicName: "createInput", isSignal: true, isRequired: true, transformFunction: null }, messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { createOutput: "createOutput", cancelRequested: "cancelRequested" }, ngImport: i0, template: `
10018
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CreateEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10019
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: CreateEditorComponent, isStandalone: true, selector: "mm-create-editor-component", inputs: { createInput: { classPropertyName: "createInput", publicName: "createInput", isSignal: true, isRequired: true, transformFunction: null }, messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { createOutput: "createOutput", cancelRequested: "cancelRequested" }, ngImport: i0, template: `
9783
10020
  <div class="entity-editor-container">
9784
10021
  <kendo-card class="basic-info-card">
9785
10022
  <kendo-card-header>
@@ -9846,7 +10083,7 @@ class CreateEditorComponent {
9846
10083
  </div>
9847
10084
  `, isInline: true, styles: [".entity-editor-container{display:flex;flex-direction:column;gap:16px;width:100%}.entity-editor-container ::ng-deep kendo-card{display:grid;grid-template-rows:auto 1fr;grid-template-columns:1fr 1fr;gap:16px;width:100%!important}.entity-editor-container ::ng-deep kendo-card kendo-card-header{grid-column:span 2;grid-row:1}.entity-editor-container ::ng-deep kendo-card kendo-card-body{grid-row:2;grid-column:span 2;display:grid;grid-template-columns:1fr 1fr;gap:16px}.entity-editor-container ::ng-deep kendo-card kendo-card-body .info-item{display:flex;flex-direction:column}.entity-editor-container ::ng-deep kendo-card kendo-card-body .info-item :first-child{grid-column:1}.entity-editor-container ::ng-deep kendo-card kendo-card-body .info-item :nth-child(2){grid-column:2}.entity-editor-container ::ng-deep kendo-card kendo-card-body .info-item label{color:var(--kendo-color-subtle, rgba(0, 0, 0, .7));margin-bottom:8px;text-transform:uppercase}.entity-editor-container .attributes-form-container ::ng-deep kendo-card:not(.basic-info-card) kendo-card-body{display:flex;flex-direction:column;gap:16px}.entity-editor-container .select-type-prompt{grid-column:span 2;text-transform:uppercase;color:var(--kendo-color-primary, #0f6dff);background-color:var(--kendo-color-surface-alt, rgba(0, 0, 0, .05));padding:16px;border-radius:8px;text-align:center;border:1px dashed var(--kendo-color-border, rgba(0, 0, 0, .1))}.entity-editor-container .entity-editor-actions{display:flex;flex-direction:row;gap:16px}.entity-editor-container .entity-editor-actions button:disabled{opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i1$3.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i1$3.CardBodyComponent, selector: "kendo-card-body" }, { kind: "component", type: i1$3.CardHeaderComponent, selector: "kendo-card-header" }, { kind: "component", type: i5.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$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: CkTypeSelectorInputComponent, selector: "mm-ck-type-selector-input", inputs: ["placeholder", "minSearchLength", "maxResults", "debounceMs", "ckModelIds", "allowAbstract", "dialogTitle", "advancedSearchLabel", "derivedFromRtCkTypeId", "disabled", "required"], outputs: ["ckTypeSelected", "ckTypeCleared"] }, { kind: "component", type: AttributesGroupComponent, selector: "mm-attributes-group", inputs: ["ckId", "parentFormGroup", "isRecord", "initialValues"] }] });
9848
10085
  }
9849
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CreateEditorComponent, decorators: [{
10086
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: CreateEditorComponent, decorators: [{
9850
10087
  type: Component,
9851
10088
  args: [{ selector: "mm-create-editor-component", imports: [
9852
10089
  ReactiveFormsModule,
@@ -9947,10 +10184,10 @@ class UpdateRuntimeEntitiesDtoGQL extends i1$2.Mutation {
9947
10184
  constructor(apollo) {
9948
10185
  super(apollo);
9949
10186
  }
9950
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UpdateRuntimeEntitiesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
9951
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UpdateRuntimeEntitiesDtoGQL, providedIn: 'root' });
10187
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UpdateRuntimeEntitiesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
10188
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UpdateRuntimeEntitiesDtoGQL, providedIn: 'root' });
9952
10189
  }
9953
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UpdateRuntimeEntitiesDtoGQL, decorators: [{
10190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UpdateRuntimeEntitiesDtoGQL, decorators: [{
9954
10191
  type: Injectable,
9955
10192
  args: [{
9956
10193
  providedIn: 'root'
@@ -10121,8 +10358,8 @@ class UpdateEditorComponent {
10121
10358
  },
10122
10359
  };
10123
10360
  }
10124
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UpdateEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10125
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: UpdateEditorComponent, isStandalone: true, selector: "mm-update-editor-component", inputs: { updateInput: { classPropertyName: "updateInput", publicName: "updateInput", isSignal: true, isRequired: true, transformFunction: null }, messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { updateOutput: "updateOutput", cancelRequested: "cancelRequested" }, ngImport: i0, template: `
10361
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UpdateEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10362
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: UpdateEditorComponent, isStandalone: true, selector: "mm-update-editor-component", inputs: { updateInput: { classPropertyName: "updateInput", publicName: "updateInput", isSignal: true, isRequired: true, transformFunction: null }, messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { updateOutput: "updateOutput", cancelRequested: "cancelRequested" }, ngImport: i0, template: `
10126
10363
  <div class="entity-editor-container">
10127
10364
  <kendo-card class="basic-info-card">
10128
10365
  <kendo-card-header>
@@ -10199,7 +10436,7 @@ class UpdateEditorComponent {
10199
10436
  </div>
10200
10437
  `, isInline: true, styles: [".entity-editor-container{display:flex;flex-direction:column;gap:16px;width:100%}.entity-editor-container ::ng-deep kendo-card{display:grid;grid-template-rows:auto 1fr;grid-template-columns:1fr 1fr;gap:16px;width:100%!important}.entity-editor-container ::ng-deep kendo-card kendo-card-header{grid-column:span 2;grid-row:1}.entity-editor-container ::ng-deep kendo-card kendo-card-body{grid-row:2;grid-column:span 2;display:grid;grid-template-columns:1fr 1fr;gap:16px}.entity-editor-container ::ng-deep kendo-card kendo-card-body .info-item{display:flex;flex-direction:column}.entity-editor-container ::ng-deep kendo-card kendo-card-body .info-item :first-child{grid-column:1}.entity-editor-container ::ng-deep kendo-card kendo-card-body .info-item :nth-child(2){grid-column:2}.entity-editor-container ::ng-deep kendo-card kendo-card-body .info-item label{color:var(--kendo-color-subtle, rgba(0, 0, 0, .7));margin-bottom:8px;text-transform:uppercase}.entity-editor-container .attributes-form-container ::ng-deep kendo-card:not(.basic-info-card) kendo-card-body{display:flex;flex-direction:column;gap:16px}.entity-editor-container .select-type-prompt{grid-column:span 2;text-transform:uppercase;color:var(--kendo-color-primary, #0f6dff);background-color:var(--kendo-color-surface-alt, rgba(0, 0, 0, .05));padding:16px;border-radius:8px;text-align:center;border:1px dashed var(--kendo-color-border, rgba(0, 0, 0, .1))}.entity-editor-container .entity-editor-actions{display:flex;flex-direction:row;gap:16px}.entity-editor-container .entity-editor-actions button:disabled{opacity:.6}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i1$3.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i1$3.CardBodyComponent, selector: "kendo-card-body" }, { kind: "component", type: i1$3.CardHeaderComponent, selector: "kendo-card-header" }, { kind: "component", type: i5.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$1.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: AttributesGroupComponent, selector: "mm-attributes-group", inputs: ["ckId", "parentFormGroup", "isRecord", "initialValues"] }] });
10201
10438
  }
10202
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UpdateEditorComponent, decorators: [{
10439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UpdateEditorComponent, decorators: [{
10203
10440
  type: Component,
10204
10441
  args: [{ selector: "mm-update-editor-component", imports: [
10205
10442
  ReactiveFormsModule,
@@ -10604,8 +10841,8 @@ class RuntimeBrowserDetailsComponent {
10604
10841
  this.createInput = undefined;
10605
10842
  this.updateInput = undefined;
10606
10843
  }
10607
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10608
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: RuntimeBrowserDetailsComponent, isStandalone: true, selector: "mm-runtime-browser-details", inputs: { selectedItem: "selectedItem", messages: "messages" }, outputs: { entitySaved: "entitySaved" }, viewQueries: [{ propertyName: "dataSourceDirective", first: true, predicate: ["dir"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
10844
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10845
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: RuntimeBrowserDetailsComponent, isStandalone: true, selector: "mm-runtime-browser-details", inputs: { selectedItem: "selectedItem", messages: "messages" }, outputs: { entitySaved: "entitySaved" }, viewQueries: [{ propertyName: "dataSourceDirective", first: true, predicate: ["dir"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
10609
10846
  <div class="runtime-browser-details">
10610
10847
  @if (isCreateModeEnabled) {
10611
10848
  <mm-create-editor-component
@@ -10737,7 +10974,7 @@ class RuntimeBrowserDetailsComponent {
10737
10974
  </div>
10738
10975
  `, isInline: true, styles: [":host{display:block;height:100%;width:100%}.runtime-browser-details{display:flex;flex-direction:column;flex:1;min-height:0;padding:24px;box-sizing:border-box;overflow-y:auto;background:linear-gradient(180deg,var(--surface-elevated) 0%,var(--deep-sea) 100%)}.runtime-browser-details .no-selection{display:flex;align-items:center;justify-content:center;flex:1;min-height:0}.runtime-browser-details .no-selection .placeholder-content{text-align:center;max-width:400px;padding:40px;background:linear-gradient(135deg,var(--iron-navy-80),var(--surface-elevated-90));border:1px solid var(--octo-mint-30);border-radius:8px 24px;box-shadow:0 0 30px var(--octo-mint-10),inset 0 0 40px var(--octo-mint-03)}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon{margin-bottom:24px}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon .k-icon{font-size:64px;color:var(--octo-mint-50);text-shadow:0 0 20px var(--octo-mint-50);animation:lcars-icon-pulse 3s ease-in-out infinite}.runtime-browser-details .no-selection .placeholder-content h3{margin:0 0 12px;font-family:Montserrat,sans-serif;font-size:1.4rem;font-weight:700;letter-spacing:2px;text-transform:uppercase;color:var(--octo-mint);text-shadow:0 0 15px var(--octo-mint-50)}.runtime-browser-details .no-selection .placeholder-content p{margin:0;font-family:Montserrat,sans-serif;font-size:.9rem;line-height:1.6;color:rgba(var(--octo-text-color),.7);letter-spacing:.5px}.runtime-browser-details .entity-details{height:100%;display:flex;flex-direction:column;overflow:hidden}.runtime-browser-details .entity-details .details-header{display:flex;align-items:center;gap:16px;padding:16px 20px 16px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;margin-bottom:20px;position:relative;box-shadow:0 4px 20px #0006,0 0 15px var(--octo-mint-08)}.runtime-browser-details .entity-details .details-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50);border-radius:4px 0 0 4px}.runtime-browser-details .entity-details .details-header .entity-icon{font-size:28px;color:var(--octo-mint);text-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .details-header .entity-title{flex:1}.runtime-browser-details .entity-details .details-header .entity-title h3{margin:0 0 6px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .details-header .entity-title .entity-type{margin:0;font-family:Roboto Mono,monospace;font-size:.8rem;color:var(--neo-cyan);background:var(--deep-sea-60);padding:4px 10px;border-radius:4px;border:1px solid var(--neo-cyan-30);display:inline-block}.runtime-browser-details .entity-details mm-entity-detail-view{flex:1;display:flex;flex-direction:column;overflow-y:auto}.runtime-browser-details .entity-details .ck-model-details,.runtime-browser-details .entity-details .ck-models-root{padding:24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative}.runtime-browser-details .entity-details .ck-model-details:before,.runtime-browser-details .entity-details .ck-models-root:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .ck-model-details h3,.runtime-browser-details .entity-details .ck-models-root h3{margin:0 0 20px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .ck-model-details p,.runtime-browser-details .entity-details .ck-models-root p{margin:0 0 12px;font-family:Roboto,sans-serif;font-size:.9rem;color:rgba(var(--octo-text-color),.85)}.runtime-browser-details .entity-details .ck-model-details p strong,.runtime-browser-details .entity-details .ck-models-root p strong{font-family:Montserrat,sans-serif;font-weight:600;font-size:.8rem;letter-spacing:.5px;text-transform:uppercase;color:var(--octo-mint-80);margin-right:12px}.runtime-browser-details .entity-details .ck-model-details p.info-text,.runtime-browser-details .entity-details .ck-models-root p.info-text{color:rgba(var(--octo-text-color),.6);font-style:italic;margin-top:24px;padding:16px 20px;background:linear-gradient(135deg,var(--neo-cyan-10),var(--neo-cyan-05));border:1px solid var(--neo-cyan-30);border-radius:4px 12px}.runtime-browser-details .entity-details .ck-type-details{display:flex;flex-direction:column;height:100%;padding:0}.runtime-browser-details .entity-details .ck-type-details .type-header{margin-bottom:20px;padding:20px 24px;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;position:relative}.runtime-browser-details .entity-details .ck-type-details .type-header:before{content:\"\";position:absolute;top:0;left:0;width:4px;height:100%;background:linear-gradient(180deg,var(--octo-mint),var(--neo-cyan),var(--royal-violet));box-shadow:0 0 10px var(--octo-mint-50)}.runtime-browser-details .entity-details .ck-type-details .type-header h3{margin:0 0 12px;font-family:Montserrat,sans-serif;font-size:1.1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-text-color)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata{display:flex;gap:10px;align-items:center}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge{padding:6px 14px;border-radius:4px;font-family:Montserrat,sans-serif;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge.abstract{background:linear-gradient(135deg,var(--royal-violet-30),var(--royal-violet-15));border:1px solid var(--royal-violet-50);color:var(--royal-violet-light-20);box-shadow:0 0 10px var(--royal-violet-30)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .badge.final{background:linear-gradient(135deg,var(--toffee-30),var(--toffee-15));border:1px solid var(--toffee-50);color:var(--toffee);box-shadow:0 0 10px var(--toffee-30)}.runtime-browser-details .entity-details .ck-type-details .type-header .type-metadata .base-type{font-family:Roboto Mono,monospace;font-size:.8rem;color:var(--neo-cyan);background:var(--deep-sea-60);padding:4px 10px;border-radius:4px;border:1px solid var(--neo-cyan-30)}.runtime-browser-details .entity-details .ck-type-details .entities-table{flex:1;display:flex;flex-direction:column;overflow:hidden;background:linear-gradient(180deg,var(--iron-navy),var(--surface-elevated));border:1px solid var(--octo-mint-30);border-radius:4px 16px;padding:20px}.runtime-browser-details .entity-details .ck-type-details .entities-table h4{margin:0 0 16px;font-family:Montserrat,sans-serif;font-size:1rem;font-weight:600;letter-spacing:1px;text-transform:uppercase;color:var(--octo-mint)}.runtime-browser-details .entity-details .ck-type-details .entities-table mm-list-view{flex:1;display:flex;flex-direction:column;overflow:hidden}@keyframes lcars-icon-pulse{0%,to{opacity:.5;transform:scale(1)}50%{opacity:.8;transform:scale(1.05)}}@media(max-width:768px){.runtime-browser-details{padding:16px}.runtime-browser-details .no-selection .placeholder-content{padding:24px}.runtime-browser-details .no-selection .placeholder-content .placeholder-icon .k-icon{font-size:48px}.runtime-browser-details .no-selection .placeholder-content h3{font-size:1.1rem}.runtime-browser-details .entity-details .details-header{flex-direction:column;align-items:flex-start;gap:12px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SVGIconModule }, { kind: "component", type: EntityDetailViewComponent, selector: "mm-entity-detail-view", inputs: ["entity", "loading", "error", "showHeader", "messages"], outputs: ["retry", "propertyChange", "navigateToEntity"] }, { 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: CkTypeEntitiesDataSourceDirective, selector: "[mmCkTypeEntitiesDataSource]", exportAs: ["mmCkTypeEntitiesDataSource"] }, { kind: "component", type: CreateEditorComponent, selector: "mm-create-editor-component", inputs: ["createInput", "messages"], outputs: ["createOutput", "cancelRequested"] }, { kind: "component", type: UpdateEditorComponent, selector: "mm-update-editor-component", inputs: ["updateInput", "messages"], outputs: ["updateOutput", "cancelRequested"] }] });
10739
10976
  }
10740
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserDetailsComponent, decorators: [{
10977
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserDetailsComponent, decorators: [{
10741
10978
  type: Component,
10742
10979
  args: [{ selector: "mm-runtime-browser-details", imports: [
10743
10980
  CommonModule,
@@ -10904,10 +11141,10 @@ class DeleteEntitiesDtoGQL extends i1$2.Mutation {
10904
11141
  constructor(apollo) {
10905
11142
  super(apollo);
10906
11143
  }
10907
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DeleteEntitiesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
10908
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DeleteEntitiesDtoGQL, providedIn: 'root' });
11144
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DeleteEntitiesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
11145
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DeleteEntitiesDtoGQL, providedIn: 'root' });
10909
11146
  }
10910
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DeleteEntitiesDtoGQL, decorators: [{
11147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: DeleteEntitiesDtoGQL, decorators: [{
10911
11148
  type: Injectable,
10912
11149
  args: [{
10913
11150
  providedIn: 'root'
@@ -10947,10 +11184,10 @@ class GetCkModelsDtoGQL extends i1$2.Query {
10947
11184
  constructor(apollo) {
10948
11185
  super(apollo);
10949
11186
  }
10950
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkModelsDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
10951
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkModelsDtoGQL, providedIn: 'root' });
11187
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkModelsDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
11188
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkModelsDtoGQL, providedIn: 'root' });
10952
11189
  }
10953
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetCkModelsDtoGQL, decorators: [{
11190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetCkModelsDtoGQL, decorators: [{
10954
11191
  type: Injectable,
10955
11192
  args: [{
10956
11193
  providedIn: 'root'
@@ -11003,10 +11240,10 @@ class GetTreeNodesDtoGQL extends i1$2.Query {
11003
11240
  constructor(apollo) {
11004
11241
  super(apollo);
11005
11242
  }
11006
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetTreeNodesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
11007
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetTreeNodesDtoGQL, providedIn: 'root' });
11243
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetTreeNodesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
11244
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetTreeNodesDtoGQL, providedIn: 'root' });
11008
11245
  }
11009
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetTreeNodesDtoGQL, decorators: [{
11246
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetTreeNodesDtoGQL, decorators: [{
11010
11247
  type: Injectable,
11011
11248
  args: [{
11012
11249
  providedIn: 'root'
@@ -11045,10 +11282,10 @@ class GetTreesDtoGQL extends i1$2.Query {
11045
11282
  constructor(apollo) {
11046
11283
  super(apollo);
11047
11284
  }
11048
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetTreesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
11049
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetTreesDtoGQL, providedIn: 'root' });
11285
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetTreesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
11286
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetTreesDtoGQL, providedIn: 'root' });
11050
11287
  }
11051
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GetTreesDtoGQL, decorators: [{
11288
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: GetTreesDtoGQL, decorators: [{
11052
11289
  type: Injectable,
11053
11290
  args: [{
11054
11291
  providedIn: 'root'
@@ -11071,10 +11308,10 @@ class UpdateTreeNodesDtoGQL extends i1$2.Mutation {
11071
11308
  constructor(apollo) {
11072
11309
  super(apollo);
11073
11310
  }
11074
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UpdateTreeNodesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
11075
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UpdateTreeNodesDtoGQL, providedIn: 'root' });
11311
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UpdateTreeNodesDtoGQL, deps: [{ token: i1$2.Apollo }], target: i0.ɵɵFactoryTarget.Injectable });
11312
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UpdateTreeNodesDtoGQL, providedIn: 'root' });
11076
11313
  }
11077
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UpdateTreeNodesDtoGQL, decorators: [{
11314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: UpdateTreeNodesDtoGQL, decorators: [{
11078
11315
  type: Injectable,
11079
11316
  args: [{
11080
11317
  providedIn: 'root'
@@ -11089,6 +11326,7 @@ class RuntimeBrowserDataSource extends OctoGraphQlHierarchyDataSource {
11089
11326
  getCkModelByIdDtoGQL = inject(GetCkModelByIdDtoGQL);
11090
11327
  deleteEntitiesDtoGQL = inject(DeleteEntitiesDtoGQL);
11091
11328
  getRuntimeEntityAssociationsByIdDtoGQL = inject(GetRuntimeEntityAssociationsByIdDtoGQL);
11329
+ updateRuntimeEntitiesDtoGQL = inject(UpdateRuntimeEntitiesDtoGQL);
11092
11330
  updateTreeNodesDtoGQL = inject(UpdateTreeNodesDtoGQL);
11093
11331
  typeHelperService = inject(TypeHelperService);
11094
11332
  isCkModelsRoot(item) {
@@ -11367,6 +11605,70 @@ class RuntimeBrowserDataSource extends OctoGraphQlHierarchyDataSource {
11367
11605
  }
11368
11606
  return true;
11369
11607
  }
11608
+ /**
11609
+ * Moves an entity to a new parent using the generic `runtimeEntities.update` mutation.
11610
+ * Works for any entity type (not just Basic/TreeNode).
11611
+ *
11612
+ * Uses the `associations` field on `RtEntityInputDto` with `roleName` set to
11613
+ * the navigation property name (e.g. "parent") and modOption CREATE/DELETE.
11614
+ *
11615
+ * @param srcObjRtId Runtime ID of the entity being moved.
11616
+ * @param srcObjCkTypeId CK type of the entity being moved.
11617
+ * @param navigationPropertyName Navigation property for the parent association (e.g. "parent").
11618
+ * @param oldParentCkTypeId CK type of the current parent.
11619
+ * @param oldParentRtId Runtime ID of the current parent.
11620
+ * @param newParentCkTypeId CK type of the new parent.
11621
+ * @param newParentRtId Runtime ID of the new parent.
11622
+ * @returns true if the move succeeded.
11623
+ */
11624
+ async updateEntityAssociation(srcObjRtId, srcObjCkTypeId, navigationPropertyName, oldParentCkTypeId, oldParentRtId, newParentCkTypeId, newParentRtId) {
11625
+ const entitiesToUpdate = [
11626
+ {
11627
+ rtId: srcObjRtId,
11628
+ item: {
11629
+ ckTypeId: srcObjCkTypeId,
11630
+ attributes: [],
11631
+ associations: [
11632
+ {
11633
+ roleName: navigationPropertyName,
11634
+ targets: [
11635
+ {
11636
+ target: {
11637
+ rtId: oldParentRtId,
11638
+ ckTypeId: oldParentCkTypeId,
11639
+ },
11640
+ modOption: AssociationModOptionsDto.DeleteDto,
11641
+ },
11642
+ {
11643
+ target: {
11644
+ rtId: newParentRtId,
11645
+ ckTypeId: newParentCkTypeId,
11646
+ },
11647
+ modOption: AssociationModOptionsDto.CreateDto,
11648
+ },
11649
+ ],
11650
+ },
11651
+ ],
11652
+ },
11653
+ },
11654
+ ];
11655
+ try {
11656
+ const response = await firstValueFrom(this.updateRuntimeEntitiesDtoGQL.mutate({
11657
+ variables: {
11658
+ entities: entitiesToUpdate,
11659
+ },
11660
+ fetchPolicy: 'network-only',
11661
+ }));
11662
+ if (response.error) {
11663
+ throw response.error;
11664
+ }
11665
+ return true;
11666
+ }
11667
+ catch (error) {
11668
+ console.error('Error on attempt to move entity by changing association', srcObjRtId, error);
11669
+ return false;
11670
+ }
11671
+ }
11370
11672
  /**
11371
11673
  * Returns ckTypeId and rtId of a parent of given runtime entity.
11372
11674
  *
@@ -11493,10 +11795,10 @@ class RuntimeBrowserDataSource extends OctoGraphQlHierarchyDataSource {
11493
11795
  return [];
11494
11796
  }
11495
11797
  }
11496
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserDataSource, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
11497
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserDataSource, providedIn: 'root' });
11798
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserDataSource, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
11799
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserDataSource, providedIn: 'root' });
11498
11800
  }
11499
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserDataSource, decorators: [{
11801
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserDataSource, decorators: [{
11500
11802
  type: Injectable,
11501
11803
  args: [{
11502
11804
  providedIn: 'root',
@@ -11513,6 +11815,7 @@ class RuntimeBrowserComponent {
11513
11815
  stateService = inject(RuntimeBrowserStateService);
11514
11816
  typeHelperService = inject(TypeHelperService);
11515
11817
  notificationService = inject(NotificationService);
11818
+ associationValidationService = inject(AssociationValidationService);
11516
11819
  isSelectedItemAnRtEntity = false;
11517
11820
  isLoading = false;
11518
11821
  isEditing = false;
@@ -11739,25 +12042,33 @@ class RuntimeBrowserComponent {
11739
12042
  console.debug(msg, event);
11740
12043
  return;
11741
12044
  }
11742
- const allowedSrcItemCkTypeIds = ['Basic/TreeNode'];
11743
- if (allowedSrcItemCkTypeIds.indexOf(event.sourceItem.ckTypeId) === -1) {
11744
- const msg = 'Moving item other than Basic/TreeNode is not supported';
11745
- this._showWarningNotification(msg);
11746
- console.debug(msg, event);
11747
- return;
11748
- }
11749
- const allowedDstParentItemCkTypeIds = ['Basic/TreeNode', 'Basic/Tree'];
11750
- if (allowedDstParentItemCkTypeIds.indexOf(event.destinationItem.ckTypeId) ===
11751
- -1) {
11752
- const msg = 'Moving item to given parent is not supported';
11753
- this._showWarningNotification(msg);
11754
- console.debug(msg, event);
11755
- return;
11756
- }
11757
12045
  try {
12046
+ const validation = await this.associationValidationService.canMove(event.sourceItem.ckTypeId, event.destinationItem.ckTypeId);
12047
+ if (!validation.allowed || !validation.navigationPropertyName) {
12048
+ const msg = validation.reason ??
12049
+ `Moving "${event.sourceItem.ckTypeId}" to "${event.destinationItem.ckTypeId}" is not allowed`;
12050
+ this._showWarningNotification(msg);
12051
+ return;
12052
+ }
11758
12053
  this.isLoading = true;
11759
12054
  this.treeDetail.setEnabledState(false);
11760
- const updateSucceeded = await this.dataSource.updateParentChildAssociation(event.sourceItem.rtId, event.sourceParent.ckTypeId, event.sourceParent.rtId, event.destinationItem.ckTypeId, event.destinationItem.rtId);
12055
+ // Use legacy TreeNode-specific mutation for Basic/TreeNode, generic mutation for all others
12056
+ let updateSucceeded;
12057
+ if (event.sourceItem.ckTypeId === 'Basic/TreeNode') {
12058
+ updateSucceeded =
12059
+ await this.dataSource.updateParentChildAssociation(event.sourceItem.rtId, event.sourceParent.ckTypeId, event.sourceParent.rtId, event.destinationItem.ckTypeId, event.destinationItem.rtId);
12060
+ }
12061
+ else {
12062
+ // Resolve actual ParentChild parent from backend — the tree parent (event.sourceParent)
12063
+ // may differ if the entity was loaded via RelatedClassification instead of ParentChild.
12064
+ const actualParent = await this.dataSource.getRuntimeEntityParentData(event.sourceItem.ckTypeId, event.sourceItem.rtId);
12065
+ if (!actualParent) {
12066
+ this._showWarningNotification('Cannot move entity: no ParentChild parent found');
12067
+ return;
12068
+ }
12069
+ updateSucceeded =
12070
+ await this.dataSource.updateEntityAssociation(event.sourceItem.rtId, event.sourceItem.ckTypeId, validation.navigationPropertyName, actualParent.ckTypeId, actualParent.rtId, event.destinationItem.ckTypeId, event.destinationItem.rtId);
12071
+ }
11761
12072
  // Update failed due to query / db error.
11762
12073
  if (!updateSucceeded) {
11763
12074
  console.debug('Cannot update association due to an error in the GraphQL request.');
@@ -11793,6 +12104,7 @@ class RuntimeBrowserComponent {
11793
12104
  }
11794
12105
  catch (error) {
11795
12106
  console.error('Error updating tree node parent after drag-and-drop:', error);
12107
+ this._showWarningNotification('An error occurred while moving the entity');
11796
12108
  }
11797
12109
  finally {
11798
12110
  this.treeDetail.setEnabledState(true);
@@ -12068,8 +12380,8 @@ class RuntimeBrowserComponent {
12068
12380
  await this.treeDetail.refreshTree();
12069
12381
  }
12070
12382
  }
12071
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12072
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: RuntimeBrowserComponent, isStandalone: true, selector: "mm-runtime-browser", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "treeDetail", first: true, predicate: ["treeDetail"], descendants: true }, { propertyName: "detailsPanel", first: true, predicate: ["detailsPanel"], descendants: true }], ngImport: i0, template: `
12383
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12384
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.8", type: RuntimeBrowserComponent, isStandalone: true, selector: "mm-runtime-browser", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "treeDetail", first: true, predicate: ["treeDetail"], descendants: true }, { propertyName: "detailsPanel", first: true, predicate: ["detailsPanel"], descendants: true }], ngImport: i0, template: `
12073
12385
  <div class="runtime-browser-container kendo-theme-provider">
12074
12386
  <!-- LCARS Header -->
12075
12387
  <div class="lcars-page-header">
@@ -12131,7 +12443,7 @@ class RuntimeBrowserComponent {
12131
12443
  </div>
12132
12444
  `, isInline: true, styles: [".runtime-browser-container{display:flex;flex-direction:column;height:100%;padding:16px;gap:16px}::ng-deep mm-base-tree-detail .k-splitter{background:transparent;border:none}::ng-deep mm-base-tree-detail .k-splitter .k-splitbar{background:linear-gradient(180deg,var(--octo-mint-30),transparent);width:4px!important}::ng-deep mm-base-tree-detail .k-splitter .k-splitbar:hover{background:linear-gradient(180deg,var(--octo-mint-50),var(--octo-mint-20))}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf{font-family:Roboto,sans-serif;transition:all .2s ease;border-radius:4px}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf:hover{background:var(--octo-mint-10);color:var(--octo-mint)}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf.k-selected{background:linear-gradient(90deg,var(--octo-mint-20),transparent);color:var(--octo-mint);border-left:3px solid var(--octo-mint)}::ng-deep mm-base-tree-detail kendo-treeview .k-treeview-item .k-treeview-leaf.k-selected:hover{background:linear-gradient(90deg,var(--octo-mint-25),transparent)}::ng-deep mm-base-tree-detail .toolbar{background:linear-gradient(90deg,var(--octo-mint-05),transparent);border-bottom:1px solid var(--octo-mint-20)}::ng-deep mm-base-tree-detail .base-tree-detail-container{height:100%;display:flex;flex-direction:column}::ng-deep mm-base-tree-detail .base-tree-detail-container .k-splitter{flex:1;min-height:0}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane{display:flex!important;flex-direction:column!important;height:100%!important}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane>mm-runtime-browser-details{display:flex!important;flex:1!important;min-height:0!important;height:100%!important}::ng-deep mm-base-tree-detail kendo-splitter-pane.detail-pane>mm-runtime-browser-details>.runtime-browser-details{flex:1;display:flex;flex-direction:column;min-height:0}@media(max-width:1024px){.runtime-browser-container{padding:12px;gap:12px}}@media(max-width:768px){.runtime-browser-container{padding:8px;gap:10px}}\n"], dependencies: [{ kind: "component", type: BaseTreeDetailComponent, selector: "mm-base-tree-detail", inputs: ["treeDataSource", "leftPaneSize", "leftToolbarActions", "rightToolbarActions"], outputs: ["nodeSelected", "nodeDropped"] }, { kind: "component", type: RuntimeBrowserDetailsComponent, selector: "mm-runtime-browser-details", inputs: ["selectedItem", "messages"], outputs: ["entitySaved"] }] });
12133
12445
  }
12134
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserComponent, decorators: [{
12446
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserComponent, decorators: [{
12135
12447
  type: Component,
12136
12448
  args: [{ selector: 'mm-runtime-browser', imports: [BaseTreeDetailComponent, RuntimeBrowserDetailsComponent], template: `
12137
12449
  <div class="runtime-browser-container kendo-theme-provider">
@@ -12207,10 +12519,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
12207
12519
  * Use as the parent component when mounting runtime browser routes as children.
12208
12520
  */
12209
12521
  class RuntimeBrowserOutletComponent {
12210
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12211
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: RuntimeBrowserOutletComponent, isStandalone: true, selector: "mm-runtime-browser-outlet", ngImport: i0, template: `<router-outlet />`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
12522
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12523
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: RuntimeBrowserOutletComponent, isStandalone: true, selector: "mm-runtime-browser-outlet", ngImport: i0, template: `<router-outlet />`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
12212
12524
  }
12213
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserOutletComponent, decorators: [{
12525
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserOutletComponent, decorators: [{
12214
12526
  type: Component,
12215
12527
  args: [{
12216
12528
  selector: 'mm-runtime-browser-outlet',
@@ -12237,10 +12549,10 @@ class RuntimeBrowserPageComponent {
12237
12549
  messages = this.injectedMessages
12238
12550
  ? this.injectedMessages
12239
12551
  : DEFAULT_RUNTIME_BROWSER_MESSAGES;
12240
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12241
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: RuntimeBrowserPageComponent, isStandalone: true, selector: "mm-runtime-browser-page", ngImport: i0, template: `<mm-runtime-browser [messages]="messages" />`, isInline: true, dependencies: [{ kind: "component", type: RuntimeBrowserComponent, selector: "mm-runtime-browser", inputs: ["messages"] }] });
12552
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12553
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: RuntimeBrowserPageComponent, isStandalone: true, selector: "mm-runtime-browser-page", ngImport: i0, template: `<mm-runtime-browser [messages]="messages" />`, isInline: true, dependencies: [{ kind: "component", type: RuntimeBrowserComponent, selector: "mm-runtime-browser", inputs: ["messages"] }] });
12242
12554
  }
12243
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RuntimeBrowserPageComponent, decorators: [{
12555
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RuntimeBrowserPageComponent, decorators: [{
12244
12556
  type: Component,
12245
12557
  args: [{
12246
12558
  selector: 'mm-runtime-browser-page',
@@ -12352,8 +12664,8 @@ class TenantSwitcherComponent {
12352
12664
  return ((this.anchor?.nativeElement.contains(target) ?? false) ||
12353
12665
  (this.popup?.nativeElement.contains(target) ?? false));
12354
12666
  }
12355
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TenantSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12356
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: TenantSwitcherComponent, isStandalone: true, selector: "mm-tenant-switcher", inputs: { currentTenantId: "currentTenantId", allowedTenants: "allowedTenants", isDenied: "isDenied" }, outputs: { tenantSelected: "tenantSelected", refreshRequested: "refreshRequested" }, host: { listeners: { "document:keydown": "onKeydown($event)", "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "anchor", first: true, predicate: ["badgeEl"], descendants: true, read: ElementRef }, { propertyName: "popup", first: true, predicate: ["popupContent"], descendants: true, read: ElementRef }], ngImport: i0, template: `
12667
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TenantSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12668
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: TenantSwitcherComponent, isStandalone: true, selector: "mm-tenant-switcher", inputs: { currentTenantId: "currentTenantId", allowedTenants: "allowedTenants", isDenied: "isDenied" }, outputs: { tenantSelected: "tenantSelected", refreshRequested: "refreshRequested" }, host: { listeners: { "document:keydown": "onKeydown($event)", "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "anchor", first: true, predicate: ["badgeEl"], descendants: true, read: ElementRef }, { propertyName: "popup", first: true, predicate: ["popupContent"], descendants: true, read: ElementRef }], ngImport: i0, template: `
12357
12669
  @if (currentTenantId) {
12358
12670
  <div #badgeEl class="tenant-badge" [class.denied]="isDenied" (click)="onToggle()">
12359
12671
  <span class="tenant-icon">{{ isDenied ? '\u26A0' : '\u25C6' }}</span>
@@ -12392,7 +12704,7 @@ class TenantSwitcherComponent {
12392
12704
  }
12393
12705
  `, isInline: true, styles: [":host{display:inline-flex;align-items:center}.tenant-badge{display:flex;align-items:center;gap:8px;padding:6px 14px;background:var(--mm-tenant-switcher-bg, var(--kendo-color-surface, transparent));border:1px solid var(--mm-tenant-switcher-border, var(--kendo-color-border, #dee2e6));border-radius:var(--mm-tenant-switcher-radius, 4px 16px 16px 4px);box-shadow:var(--mm-tenant-switcher-shadow, none);cursor:pointer;transition:all .2s ease}.tenant-badge:hover{background:var(--mm-tenant-switcher-bg-hover, var(--kendo-color-base-hover, rgba(0, 0, 0, .04)));box-shadow:var(--mm-tenant-switcher-shadow-hover, var(--mm-tenant-switcher-shadow, none))}.tenant-icon{font-size:.7rem;color:var(--mm-tenant-switcher-accent, var(--kendo-color-primary, #ff6358));animation:var(--mm-tenant-switcher-icon-animation, none)}.tenant-name{font-family:var(--mm-tenant-switcher-font, inherit);font-size:.85rem;font-weight:600;letter-spacing:1px;color:var(--mm-tenant-switcher-accent, var(--kendo-color-primary, #ff6358));text-transform:uppercase;text-shadow:var(--mm-tenant-switcher-text-shadow, none)}.denied{background:var(--mm-tenant-switcher-denied-bg, var(--mm-tenant-switcher-bg, var(--kendo-color-surface, transparent)));border-color:var(--mm-tenant-switcher-denied-border, var(--kendo-color-error, #d9534f));box-shadow:var(--mm-tenant-switcher-denied-shadow, none)}.denied .tenant-icon,.denied .tenant-name{color:var(--mm-tenant-switcher-denied-accent, var(--kendo-color-error, #d9534f));text-shadow:var(--mm-tenant-switcher-denied-text-shadow, none)}.denied-label{font-family:var(--mm-tenant-switcher-font, inherit);font-size:.55rem;font-weight:700;letter-spacing:1px;color:var(--mm-tenant-switcher-denied-accent, var(--kendo-color-error, #d9534f));background:var(--mm-tenant-switcher-denied-label-bg, color-mix(in srgb, var(--kendo-color-error, #d9534f) 15%, transparent));padding:2px 6px;border-radius:3px}.tenant-popup{min-width:220px;padding:8px 0;background:var(--kendo-color-surface, #fff);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.tenant-popup-header{display:flex;align-items:center;justify-content:space-between;padding:8px 16px;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #666);border-bottom:1px solid var(--kendo-color-border, #dee2e6);margin-bottom:4px}.refresh-btn{padding:2px;min-width:unset}.spinning{animation:spin .8s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.tenant-list{list-style:none;margin:0;padding:0}.tenant-list-item{display:flex;align-items:center;gap:10px;padding:8px 16px;cursor:pointer;font-size:.85rem;transition:background .15s ease}.tenant-list-item:hover{background:var(--kendo-color-base-hover, rgba(0, 0, 0, .04))}.tenant-list-item.active{color:var(--kendo-color-primary, #ff6358);font-weight:600}.tenant-list-icon{font-size:.5rem;color:var(--kendo-color-subtle, #666)}.tenant-list-item.active .tenant-list-icon{color:var(--kendo-color-primary, #ff6358)}@keyframes mm-icon-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.1)}}\n"], dependencies: [{ kind: "component", type: PopupComponent, selector: "kendo-popup", inputs: ["animate", "anchor", "anchorAlign", "collision", "popupAlign", "copyAnchorStyles", "popupClass", "positionMode", "offset", "margin"], outputs: ["anchorViewportLeave", "close", "open", "positionChange"], exportAs: ["kendo-popup"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }] });
12394
12706
  }
12395
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TenantSwitcherComponent, decorators: [{
12707
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: TenantSwitcherComponent, decorators: [{
12396
12708
  type: Component,
12397
12709
  args: [{ selector: 'mm-tenant-switcher', standalone: true, imports: [
12398
12710
  PopupComponent,
@@ -12484,5 +12796,5 @@ function provideOctoUi() {
12484
12796
  * Generated bundle index. Do not edit.
12485
12797
  */
12486
12798
 
12487
- export { AttributeSelectorDialogComponent, AttributeSelectorDialogService, AttributeSortSelectorDialogComponent, AttributeSortSelectorDialogService, AttributeValueTypeDto, CkTypeSelectorDialogComponent, CkTypeSelectorDialogService, CkTypeSelectorInputComponent, DEFAULT_RUNTIME_BROWSER_MESSAGES, DefaultPropertyCategory, EntityDetailComponent, EntityIdInfoComponent, FieldFilterEditorComponent, OctoGraphQlDataSource, OctoGraphQlHierarchyDataSource, OctoLoaderComponent, PropertyConverterService, PropertyDisplayMode, PropertyGridComponent, PropertyValueDisplayComponent, RUNTIME_BROWSER_MESSAGES, RtEntityIdHelper, RuntimeBrowserComponent, RuntimeBrowserOutletComponent, RuntimeBrowserPageComponent, RuntimeBrowserStateService, RuntimeEntityVariableDialogComponent, RuntimeEntityVariableDialogService, TenantSwitcherComponent, account_tree, add, analytics, app_registration, article, botService, category, chat, checklist, code, component_exchange, computer, createRuntimeBrowserRoutes, customer, dashboard, event_list, graphic_eq, group, identityService, insert_link, manage_accounts, more_time, notifications, page_info, pages, person_search, playlist_add_check, pool, power, provideOctoUi, publicIcon, query_builder, schedule_send, settings, sort, storage, swagger, swagger_asset, swagger_bot, swagger_communication, swagger_identity, team_dashboard, tenancy, text_snippet, travel_explore, user_diagnostics, webhook, work };
12799
+ export { AssociationValidationService, AttributeSelectorDialogComponent, AttributeSelectorDialogService, AttributeSortSelectorDialogComponent, AttributeSortSelectorDialogService, AttributeValueTypeDto, CkTypeSelectorDialogComponent, CkTypeSelectorDialogService, CkTypeSelectorInputComponent, DEFAULT_RUNTIME_BROWSER_MESSAGES, DefaultPropertyCategory, EntityDetailComponent, EntityIdInfoComponent, FieldFilterEditorComponent, OctoGraphQlDataSource, OctoGraphQlHierarchyDataSource, OctoLoaderComponent, PropertyConverterService, PropertyDisplayMode, PropertyGridComponent, PropertyValueDisplayComponent, RUNTIME_BROWSER_MESSAGES, RtEntityIdHelper, RuntimeBrowserComponent, RuntimeBrowserOutletComponent, RuntimeBrowserPageComponent, RuntimeBrowserStateService, RuntimeEntityVariableDialogComponent, RuntimeEntityVariableDialogService, TenantSwitcherComponent, account_tree, add, analytics, app_registration, article, botService, category, chat, checklist, code, component_exchange, computer, createRuntimeBrowserRoutes, customer, dashboard, event_list, graphic_eq, group, identityService, insert_link, manage_accounts, more_time, notifications, page_info, pages, person_search, playlist_add_check, pool, power, provideOctoUi, publicIcon, query_builder, schedule_send, settings, sort, storage, swagger, swagger_asset, swagger_bot, swagger_communication, swagger_identity, team_dashboard, tenancy, text_snippet, travel_explore, user_diagnostics, webhook, work };
12488
12800
  //# sourceMappingURL=meshmakers-octo-ui.mjs.map