@meshmakers/octo-ui 3.3.410 → 3.3.430
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.
|
@@ -17,7 +17,7 @@ import * as i3$1 from '@progress/kendo-angular-dropdowns';
|
|
|
17
17
|
import { DropDownListModule, DropDownsModule, AutoCompleteModule } from '@progress/kendo-angular-dropdowns';
|
|
18
18
|
import * as i5$1 from '@progress/kendo-angular-icons';
|
|
19
19
|
import { IconsModule, SVGIconModule } from '@progress/kendo-angular-icons';
|
|
20
|
-
import { searchIcon, sortAscSmallIcon, sortDescSmallIcon,
|
|
20
|
+
import { searchIcon, sortAscSmallIcon, sortDescSmallIcon, chevronRightIcon, chevronDownIcon, downloadIcon, fileIcon, folderIcon, calendarIcon, checkboxCheckedIcon, listUnorderedIcon, filterClearIcon, arrowRightIcon, arrowLeftIcon, chevronDoubleRightIcon, chevronDoubleLeftIcon, arrowUpIcon, arrowDownIcon, plusIcon, minusIcon, trashIcon, dollarIcon, copyIcon } from '@progress/kendo-svg-icons';
|
|
21
21
|
import * as i5 from '@progress/kendo-angular-dialog';
|
|
22
22
|
import { DialogContentBase, DialogRef, DialogModule, DialogService } from '@progress/kendo-angular-dialog';
|
|
23
23
|
import { Subject, firstValueFrom, of, forkJoin, Subscription } from 'rxjs';
|
|
@@ -910,485 +910,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
910
910
|
}]
|
|
911
911
|
}] });
|
|
912
912
|
|
|
913
|
-
class CkTypeSelectorDialogComponent extends DialogContentBase {
|
|
914
|
-
ckTypeSelectorService = inject(CkTypeSelectorService);
|
|
915
|
-
searchSubject = new Subject();
|
|
916
|
-
subscriptions = new Subscription();
|
|
917
|
-
searchIcon = searchIcon;
|
|
918
|
-
filterClearIcon = filterClearIcon;
|
|
919
|
-
dialogTitle = 'Select Construction Kit Type';
|
|
920
|
-
allowAbstract = false;
|
|
921
|
-
searchText = '';
|
|
922
|
-
selectedModel = null;
|
|
923
|
-
availableModels = [];
|
|
924
|
-
gridData = { data: [], total: 0 };
|
|
925
|
-
isLoading = false;
|
|
926
|
-
pageSize = 50;
|
|
927
|
-
skip = 0;
|
|
928
|
-
selectedKeys = [];
|
|
929
|
-
selectedType = null;
|
|
930
|
-
// Selection key function - returns fullName as unique identifier
|
|
931
|
-
selectItemBy = (context) => context.dataItem.fullName;
|
|
932
|
-
initialCkModelIds;
|
|
933
|
-
constructor() {
|
|
934
|
-
super(inject(DialogRef));
|
|
935
|
-
}
|
|
936
|
-
ngOnInit() {
|
|
937
|
-
const data = this.dialog.content?.instance?.data;
|
|
938
|
-
if (data) {
|
|
939
|
-
this.dialogTitle = data.dialogTitle || 'Select Construction Kit Type';
|
|
940
|
-
this.allowAbstract = data.allowAbstract ?? false;
|
|
941
|
-
this.initialCkModelIds = data.ckModelIds;
|
|
942
|
-
if (data.selectedCkTypeId) {
|
|
943
|
-
this.selectedKeys = [data.selectedCkTypeId];
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
// Set up search debouncing
|
|
947
|
-
this.subscriptions.add(this.searchSubject.pipe(debounceTime(300), distinctUntilChanged()).subscribe(() => {
|
|
948
|
-
this.skip = 0;
|
|
949
|
-
this.loadTypes();
|
|
950
|
-
}));
|
|
951
|
-
// Load initial types and extract available models
|
|
952
|
-
this.loadTypes();
|
|
953
|
-
this.loadAvailableModels();
|
|
954
|
-
}
|
|
955
|
-
ngOnDestroy() {
|
|
956
|
-
this.subscriptions.unsubscribe();
|
|
957
|
-
}
|
|
958
|
-
loadTypes() {
|
|
959
|
-
this.isLoading = true;
|
|
960
|
-
const ckModelIds = this.selectedModel
|
|
961
|
-
? [this.selectedModel]
|
|
962
|
-
: this.initialCkModelIds;
|
|
963
|
-
this.subscriptions.add(this.ckTypeSelectorService.getCkTypes({
|
|
964
|
-
ckModelIds,
|
|
965
|
-
searchText: this.searchText || undefined,
|
|
966
|
-
first: this.pageSize,
|
|
967
|
-
skip: this.skip
|
|
968
|
-
}).subscribe({
|
|
969
|
-
next: result => {
|
|
970
|
-
this.gridData = {
|
|
971
|
-
data: result.items,
|
|
972
|
-
total: result.totalCount
|
|
973
|
-
};
|
|
974
|
-
// Restore selection if exists
|
|
975
|
-
if (this.selectedKeys.length > 0) {
|
|
976
|
-
const selectedItem = result.items.find(item => item.fullName === this.selectedKeys[0]);
|
|
977
|
-
if (selectedItem) {
|
|
978
|
-
this.selectedType = selectedItem;
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
this.isLoading = false;
|
|
982
|
-
},
|
|
983
|
-
error: () => {
|
|
984
|
-
this.isLoading = false;
|
|
985
|
-
this.gridData = { data: [], total: 0 };
|
|
986
|
-
}
|
|
987
|
-
}));
|
|
988
|
-
}
|
|
989
|
-
loadAvailableModels() {
|
|
990
|
-
// Load all types to extract unique models
|
|
991
|
-
this.subscriptions.add(this.ckTypeSelectorService.getCkTypes({
|
|
992
|
-
first: 1000
|
|
993
|
-
}).subscribe(result => {
|
|
994
|
-
const modelSet = new Set();
|
|
995
|
-
result.items.forEach(item => {
|
|
996
|
-
// Extract model from fullName (format: "ModelName-Version/TypeName-Version")
|
|
997
|
-
const modelMatch = item.fullName.match(/^([^/]+)\//);
|
|
998
|
-
if (modelMatch) {
|
|
999
|
-
modelSet.add(modelMatch[1]);
|
|
1000
|
-
}
|
|
1001
|
-
});
|
|
1002
|
-
this.availableModels = Array.from(modelSet).sort();
|
|
1003
|
-
}));
|
|
1004
|
-
}
|
|
1005
|
-
onSearchChange(value) {
|
|
1006
|
-
this.searchSubject.next(value);
|
|
1007
|
-
}
|
|
1008
|
-
onModelFilterChange(_value) {
|
|
1009
|
-
this.skip = 0;
|
|
1010
|
-
this.loadTypes();
|
|
1011
|
-
}
|
|
1012
|
-
clearFilters() {
|
|
1013
|
-
this.searchText = '';
|
|
1014
|
-
this.selectedModel = null;
|
|
1015
|
-
this.skip = 0;
|
|
1016
|
-
this.loadTypes();
|
|
1017
|
-
}
|
|
1018
|
-
onPageChange(event) {
|
|
1019
|
-
this.skip = event.skip;
|
|
1020
|
-
this.pageSize = event.take;
|
|
1021
|
-
this.loadTypes();
|
|
1022
|
-
}
|
|
1023
|
-
onSelectionChange(event) {
|
|
1024
|
-
const selectedItems = event.selectedRows;
|
|
1025
|
-
if (selectedItems && selectedItems.length > 0) {
|
|
1026
|
-
this.selectedType = selectedItems[0].dataItem;
|
|
1027
|
-
}
|
|
1028
|
-
else {
|
|
1029
|
-
this.selectedType = null;
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
onCancel() {
|
|
1033
|
-
this.dialog.close();
|
|
1034
|
-
}
|
|
1035
|
-
onConfirm() {
|
|
1036
|
-
if (this.selectedType) {
|
|
1037
|
-
const result = {
|
|
1038
|
-
selectedCkType: this.selectedType
|
|
1039
|
-
};
|
|
1040
|
-
this.dialog.close(result);
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1044
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.5", type: CkTypeSelectorDialogComponent, isStandalone: true, selector: "mm-ck-type-selector-dialog", usesInheritance: true, ngImport: i0, template: `
|
|
1045
|
-
<div class="ck-type-selector-container">
|
|
1046
|
-
<div class="filter-container">
|
|
1047
|
-
<div class="filter-row">
|
|
1048
|
-
<div class="filter-item">
|
|
1049
|
-
<label>Model Filter</label>
|
|
1050
|
-
<kendo-combobox
|
|
1051
|
-
[data]="availableModels"
|
|
1052
|
-
[(ngModel)]="selectedModel"
|
|
1053
|
-
(valueChange)="onModelFilterChange($event)"
|
|
1054
|
-
[allowCustom]="false"
|
|
1055
|
-
[clearButton]="true"
|
|
1056
|
-
placeholder="All Models"
|
|
1057
|
-
class="filter-input">
|
|
1058
|
-
</kendo-combobox>
|
|
1059
|
-
</div>
|
|
1060
|
-
<div class="filter-item flex-grow">
|
|
1061
|
-
<label>Type Search</label>
|
|
1062
|
-
<kendo-textbox
|
|
1063
|
-
[(ngModel)]="searchText"
|
|
1064
|
-
(ngModelChange)="onSearchChange($event)"
|
|
1065
|
-
placeholder="Search types..."
|
|
1066
|
-
class="filter-input">
|
|
1067
|
-
<ng-template kendoTextBoxSuffixTemplate>
|
|
1068
|
-
<button kendoButton [svgIcon]="searchIcon" fillMode="clear" size="small"></button>
|
|
1069
|
-
</ng-template>
|
|
1070
|
-
</kendo-textbox>
|
|
1071
|
-
</div>
|
|
1072
|
-
<div class="filter-item filter-actions">
|
|
1073
|
-
<label> </label>
|
|
1074
|
-
<button kendoButton [svgIcon]="filterClearIcon" (click)="clearFilters()" title="Clear filters"></button>
|
|
1075
|
-
</div>
|
|
1076
|
-
</div>
|
|
1077
|
-
</div>
|
|
1078
|
-
|
|
1079
|
-
<div class="grid-container">
|
|
1080
|
-
<kendo-grid
|
|
1081
|
-
[data]="gridData"
|
|
1082
|
-
[loading]="isLoading"
|
|
1083
|
-
[height]="400"
|
|
1084
|
-
[selectable]="{ mode: 'single' }"
|
|
1085
|
-
[pageable]="{ pageSizes: [25, 50, 100] }"
|
|
1086
|
-
[pageSize]="pageSize"
|
|
1087
|
-
[skip]="skip"
|
|
1088
|
-
(pageChange)="onPageChange($event)"
|
|
1089
|
-
(selectionChange)="onSelectionChange($event)"
|
|
1090
|
-
[kendoGridSelectBy]="selectItemBy"
|
|
1091
|
-
[(selectedKeys)]="selectedKeys"
|
|
1092
|
-
class="type-grid">
|
|
1093
|
-
<kendo-grid-column field="rtCkTypeId" title="Type" [width]="300">
|
|
1094
|
-
<ng-template kendoGridCellTemplate let-dataItem>
|
|
1095
|
-
<span [class.abstract-type]="dataItem.isAbstract" [class.final-type]="dataItem.isFinal">
|
|
1096
|
-
{{ dataItem.rtCkTypeId }}
|
|
1097
|
-
</span>
|
|
1098
|
-
<span *ngIf="dataItem.isAbstract" class="type-badge abstract">abstract</span>
|
|
1099
|
-
<span *ngIf="dataItem.isFinal" class="type-badge final">final</span>
|
|
1100
|
-
</ng-template>
|
|
1101
|
-
</kendo-grid-column>
|
|
1102
|
-
<kendo-grid-column field="baseTypeRtCkTypeId" title="Base Type" [width]="200">
|
|
1103
|
-
<ng-template kendoGridCellTemplate let-dataItem>
|
|
1104
|
-
{{ dataItem.baseTypeRtCkTypeId || '-' }}
|
|
1105
|
-
</ng-template>
|
|
1106
|
-
</kendo-grid-column>
|
|
1107
|
-
<kendo-grid-column field="description" title="Description">
|
|
1108
|
-
<ng-template kendoGridCellTemplate let-dataItem>
|
|
1109
|
-
{{ dataItem.description || '-' }}
|
|
1110
|
-
</ng-template>
|
|
1111
|
-
</kendo-grid-column>
|
|
1112
|
-
</kendo-grid>
|
|
1113
|
-
</div>
|
|
1114
|
-
|
|
1115
|
-
<div class="selection-info" *ngIf="selectedType">
|
|
1116
|
-
<strong>Selected:</strong> {{ selectedType.rtCkTypeId }}
|
|
1117
|
-
</div>
|
|
1118
|
-
</div>
|
|
1119
|
-
|
|
1120
|
-
<kendo-dialog-actions>
|
|
1121
|
-
<button kendoButton (click)="onCancel()">Cancel</button>
|
|
1122
|
-
<button kendoButton themeColor="primary" [disabled]="!selectedType || (selectedType.isAbstract && !allowAbstract)" (click)="onConfirm()">OK</button>
|
|
1123
|
-
</kendo-dialog-actions>
|
|
1124
|
-
`, isInline: true, styles: [".ck-type-selector-container{display:flex;flex-direction:column;height:100%;padding:20px;min-width:700px;box-sizing:border-box}.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}.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}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i2$1.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: i2$1.SelectionDirective, selector: "[kendoGridSelectBy]" }, { kind: "component", type: i2$1.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i2$1.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3.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: i4.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: i4.TextBoxSuffixTemplateDirective, selector: "[kendoTextBoxSuffixTemplate]", inputs: ["showSeparator"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i3$1.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: DialogModule }, { kind: "component", type: i5.DialogActionsComponent, selector: "kendo-dialog-actions", inputs: ["actions", "layout"], outputs: ["action"] }] });
|
|
1125
|
-
}
|
|
1126
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogComponent, decorators: [{
|
|
1127
|
-
type: Component,
|
|
1128
|
-
args: [{ selector: 'mm-ck-type-selector-dialog', standalone: true, imports: [
|
|
1129
|
-
CommonModule,
|
|
1130
|
-
FormsModule,
|
|
1131
|
-
GridModule,
|
|
1132
|
-
ButtonsModule,
|
|
1133
|
-
InputsModule,
|
|
1134
|
-
DropDownsModule,
|
|
1135
|
-
IconsModule,
|
|
1136
|
-
LoaderModule,
|
|
1137
|
-
DialogModule
|
|
1138
|
-
], template: `
|
|
1139
|
-
<div class="ck-type-selector-container">
|
|
1140
|
-
<div class="filter-container">
|
|
1141
|
-
<div class="filter-row">
|
|
1142
|
-
<div class="filter-item">
|
|
1143
|
-
<label>Model Filter</label>
|
|
1144
|
-
<kendo-combobox
|
|
1145
|
-
[data]="availableModels"
|
|
1146
|
-
[(ngModel)]="selectedModel"
|
|
1147
|
-
(valueChange)="onModelFilterChange($event)"
|
|
1148
|
-
[allowCustom]="false"
|
|
1149
|
-
[clearButton]="true"
|
|
1150
|
-
placeholder="All Models"
|
|
1151
|
-
class="filter-input">
|
|
1152
|
-
</kendo-combobox>
|
|
1153
|
-
</div>
|
|
1154
|
-
<div class="filter-item flex-grow">
|
|
1155
|
-
<label>Type Search</label>
|
|
1156
|
-
<kendo-textbox
|
|
1157
|
-
[(ngModel)]="searchText"
|
|
1158
|
-
(ngModelChange)="onSearchChange($event)"
|
|
1159
|
-
placeholder="Search types..."
|
|
1160
|
-
class="filter-input">
|
|
1161
|
-
<ng-template kendoTextBoxSuffixTemplate>
|
|
1162
|
-
<button kendoButton [svgIcon]="searchIcon" fillMode="clear" size="small"></button>
|
|
1163
|
-
</ng-template>
|
|
1164
|
-
</kendo-textbox>
|
|
1165
|
-
</div>
|
|
1166
|
-
<div class="filter-item filter-actions">
|
|
1167
|
-
<label> </label>
|
|
1168
|
-
<button kendoButton [svgIcon]="filterClearIcon" (click)="clearFilters()" title="Clear filters"></button>
|
|
1169
|
-
</div>
|
|
1170
|
-
</div>
|
|
1171
|
-
</div>
|
|
1172
|
-
|
|
1173
|
-
<div class="grid-container">
|
|
1174
|
-
<kendo-grid
|
|
1175
|
-
[data]="gridData"
|
|
1176
|
-
[loading]="isLoading"
|
|
1177
|
-
[height]="400"
|
|
1178
|
-
[selectable]="{ mode: 'single' }"
|
|
1179
|
-
[pageable]="{ pageSizes: [25, 50, 100] }"
|
|
1180
|
-
[pageSize]="pageSize"
|
|
1181
|
-
[skip]="skip"
|
|
1182
|
-
(pageChange)="onPageChange($event)"
|
|
1183
|
-
(selectionChange)="onSelectionChange($event)"
|
|
1184
|
-
[kendoGridSelectBy]="selectItemBy"
|
|
1185
|
-
[(selectedKeys)]="selectedKeys"
|
|
1186
|
-
class="type-grid">
|
|
1187
|
-
<kendo-grid-column field="rtCkTypeId" title="Type" [width]="300">
|
|
1188
|
-
<ng-template kendoGridCellTemplate let-dataItem>
|
|
1189
|
-
<span [class.abstract-type]="dataItem.isAbstract" [class.final-type]="dataItem.isFinal">
|
|
1190
|
-
{{ dataItem.rtCkTypeId }}
|
|
1191
|
-
</span>
|
|
1192
|
-
<span *ngIf="dataItem.isAbstract" class="type-badge abstract">abstract</span>
|
|
1193
|
-
<span *ngIf="dataItem.isFinal" class="type-badge final">final</span>
|
|
1194
|
-
</ng-template>
|
|
1195
|
-
</kendo-grid-column>
|
|
1196
|
-
<kendo-grid-column field="baseTypeRtCkTypeId" title="Base Type" [width]="200">
|
|
1197
|
-
<ng-template kendoGridCellTemplate let-dataItem>
|
|
1198
|
-
{{ dataItem.baseTypeRtCkTypeId || '-' }}
|
|
1199
|
-
</ng-template>
|
|
1200
|
-
</kendo-grid-column>
|
|
1201
|
-
<kendo-grid-column field="description" title="Description">
|
|
1202
|
-
<ng-template kendoGridCellTemplate let-dataItem>
|
|
1203
|
-
{{ dataItem.description || '-' }}
|
|
1204
|
-
</ng-template>
|
|
1205
|
-
</kendo-grid-column>
|
|
1206
|
-
</kendo-grid>
|
|
1207
|
-
</div>
|
|
1208
|
-
|
|
1209
|
-
<div class="selection-info" *ngIf="selectedType">
|
|
1210
|
-
<strong>Selected:</strong> {{ selectedType.rtCkTypeId }}
|
|
1211
|
-
</div>
|
|
1212
|
-
</div>
|
|
1213
|
-
|
|
1214
|
-
<kendo-dialog-actions>
|
|
1215
|
-
<button kendoButton (click)="onCancel()">Cancel</button>
|
|
1216
|
-
<button kendoButton themeColor="primary" [disabled]="!selectedType || (selectedType.isAbstract && !allowAbstract)" (click)="onConfirm()">OK</button>
|
|
1217
|
-
</kendo-dialog-actions>
|
|
1218
|
-
`, styles: [".ck-type-selector-container{display:flex;flex-direction:column;height:100%;padding:20px;min-width:700px;box-sizing:border-box}.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}.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}\n"] }]
|
|
1219
|
-
}], ctorParameters: () => [] });
|
|
1220
|
-
|
|
1221
|
-
class CkTypeSelectorDialogService {
|
|
1222
|
-
dialogService = inject(DialogService);
|
|
1223
|
-
/**
|
|
1224
|
-
* Opens the CkType selector dialog
|
|
1225
|
-
* @param options Dialog options
|
|
1226
|
-
* @returns Promise that resolves with the result containing selected CkType and confirmation status
|
|
1227
|
-
*/
|
|
1228
|
-
async openCkTypeSelector(options = {}) {
|
|
1229
|
-
const data = {
|
|
1230
|
-
selectedCkTypeId: options.selectedCkTypeId,
|
|
1231
|
-
ckModelIds: options.ckModelIds,
|
|
1232
|
-
dialogTitle: options.dialogTitle,
|
|
1233
|
-
allowAbstract: options.allowAbstract
|
|
1234
|
-
};
|
|
1235
|
-
const dialogRef = this.dialogService.open({
|
|
1236
|
-
content: CkTypeSelectorDialogComponent,
|
|
1237
|
-
width: 900,
|
|
1238
|
-
height: 650,
|
|
1239
|
-
minWidth: 750,
|
|
1240
|
-
minHeight: 550,
|
|
1241
|
-
title: options.dialogTitle || 'Select Construction Kit Type'
|
|
1242
|
-
});
|
|
1243
|
-
// Pass data to the component
|
|
1244
|
-
if (dialogRef.content?.instance) {
|
|
1245
|
-
dialogRef.content.instance.data = data;
|
|
1246
|
-
}
|
|
1247
|
-
try {
|
|
1248
|
-
const result = await firstValueFrom(dialogRef.result);
|
|
1249
|
-
if (result && typeof result === 'object' && 'selectedCkType' in result) {
|
|
1250
|
-
// User clicked OK and we have a result
|
|
1251
|
-
const dialogResult = result;
|
|
1252
|
-
return {
|
|
1253
|
-
confirmed: true,
|
|
1254
|
-
selectedCkType: dialogResult.selectedCkType
|
|
1255
|
-
};
|
|
1256
|
-
}
|
|
1257
|
-
else {
|
|
1258
|
-
// User clicked Cancel or closed dialog
|
|
1259
|
-
return {
|
|
1260
|
-
confirmed: false,
|
|
1261
|
-
selectedCkType: null
|
|
1262
|
-
};
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
catch {
|
|
1266
|
-
// Dialog was closed without result (e.g., ESC key, X button)
|
|
1267
|
-
return {
|
|
1268
|
-
confirmed: false,
|
|
1269
|
-
selectedCkType: null
|
|
1270
|
-
};
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1274
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogService });
|
|
1275
|
-
}
|
|
1276
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogService, decorators: [{
|
|
1277
|
-
type: Injectable
|
|
1278
|
-
}] });
|
|
1279
|
-
|
|
1280
|
-
// noinspection JSUnusedGlobalSymbols
|
|
1281
|
-
class OctoGraphQlDataSource extends DataSourceTyped {
|
|
1282
|
-
_searchFilterAttributePaths = [];
|
|
1283
|
-
// noinspection JSUnusedGlobalSymbols
|
|
1284
|
-
constructor(listViewComponent) {
|
|
1285
|
-
super(listViewComponent);
|
|
1286
|
-
}
|
|
1287
|
-
get searchFilterAttributePaths() {
|
|
1288
|
-
return this._searchFilterAttributePaths;
|
|
1289
|
-
}
|
|
1290
|
-
set searchFilterAttributePaths(value) {
|
|
1291
|
-
this._searchFilterAttributePaths = value;
|
|
1292
|
-
}
|
|
1293
|
-
// noinspection JSUnusedGlobalSymbols
|
|
1294
|
-
getFieldFilterDefinitions(state) {
|
|
1295
|
-
let fieldFilters = null;
|
|
1296
|
-
if (state.filter?.filters) {
|
|
1297
|
-
fieldFilters = state.filter.filters.map((f) => {
|
|
1298
|
-
if (isCompositeFilterDescriptor(f)) {
|
|
1299
|
-
throw new Error('Composite filter descriptor not supported');
|
|
1300
|
-
}
|
|
1301
|
-
const { operator, value } = OctoGraphQlDataSource.getOperatorAndValue(f.operator, f.value);
|
|
1302
|
-
return {
|
|
1303
|
-
attributePath: f.field,
|
|
1304
|
-
operator: operator,
|
|
1305
|
-
comparisonValue: value
|
|
1306
|
-
};
|
|
1307
|
-
});
|
|
1308
|
-
}
|
|
1309
|
-
return fieldFilters;
|
|
1310
|
-
}
|
|
1311
|
-
// noinspection JSUnusedGlobalSymbols
|
|
1312
|
-
getSearchFilterDefinitions(textSearchValue) {
|
|
1313
|
-
let searchFilterDto = null;
|
|
1314
|
-
if (textSearchValue) {
|
|
1315
|
-
searchFilterDto = {
|
|
1316
|
-
type: SearchFilterTypesDto.AttributeFilterDto,
|
|
1317
|
-
attributePaths: this.searchFilterAttributePaths,
|
|
1318
|
-
searchTerm: textSearchValue,
|
|
1319
|
-
};
|
|
1320
|
-
}
|
|
1321
|
-
return searchFilterDto;
|
|
1322
|
-
}
|
|
1323
|
-
// noinspection JSUnusedGlobalSymbols
|
|
1324
|
-
getSortDefinitions(state) {
|
|
1325
|
-
let sort = null;
|
|
1326
|
-
if (state.sort) {
|
|
1327
|
-
sort = new Array();
|
|
1328
|
-
state.sort.forEach((s) => {
|
|
1329
|
-
switch (s.dir) {
|
|
1330
|
-
case 'asc':
|
|
1331
|
-
sort?.push({
|
|
1332
|
-
attributePath: s.field,
|
|
1333
|
-
sortOrder: SortOrdersDto.AscendingDto
|
|
1334
|
-
});
|
|
1335
|
-
break;
|
|
1336
|
-
case 'desc':
|
|
1337
|
-
sort?.push({
|
|
1338
|
-
attributePath: s.field,
|
|
1339
|
-
sortOrder: SortOrdersDto.DescendingDto,
|
|
1340
|
-
});
|
|
1341
|
-
break;
|
|
1342
|
-
default:
|
|
1343
|
-
sort?.push({
|
|
1344
|
-
attributePath: s.field,
|
|
1345
|
-
sortOrder: SortOrdersDto.DefaultDto,
|
|
1346
|
-
});
|
|
1347
|
-
break;
|
|
1348
|
-
}
|
|
1349
|
-
});
|
|
1350
|
-
}
|
|
1351
|
-
return sort;
|
|
1352
|
-
}
|
|
1353
|
-
static getOperatorAndValue(operator, value) {
|
|
1354
|
-
switch (operator) {
|
|
1355
|
-
case 'eq':
|
|
1356
|
-
return { operator: FieldFilterOperatorsDto.EqualsDto, value: value };
|
|
1357
|
-
case 'neq':
|
|
1358
|
-
return { operator: FieldFilterOperatorsDto.NotEqualsDto, value: value };
|
|
1359
|
-
case 'lt':
|
|
1360
|
-
return { operator: FieldFilterOperatorsDto.LessThanDto, value: value };
|
|
1361
|
-
case 'lte':
|
|
1362
|
-
return { operator: FieldFilterOperatorsDto.LessEqualThanDto, value: value };
|
|
1363
|
-
case 'gt':
|
|
1364
|
-
return { operator: FieldFilterOperatorsDto.GreaterThanDto, value: value };
|
|
1365
|
-
case 'gte':
|
|
1366
|
-
return { operator: FieldFilterOperatorsDto.GreaterEqualThanDto, value: value };
|
|
1367
|
-
case 'contains':
|
|
1368
|
-
return { operator: FieldFilterOperatorsDto.LikeDto, value: value };
|
|
1369
|
-
case 'doesnotcontain':
|
|
1370
|
-
return { operator: FieldFilterOperatorsDto.MatchRegExDto, value: `^(?!.*${value}).*$` };
|
|
1371
|
-
case 'startswith':
|
|
1372
|
-
return { operator: FieldFilterOperatorsDto.MatchRegExDto, value: value + '.*' };
|
|
1373
|
-
case 'endswith':
|
|
1374
|
-
return { operator: FieldFilterOperatorsDto.MatchRegExDto, value: '.*' + value };
|
|
1375
|
-
case 'isnull':
|
|
1376
|
-
return { operator: FieldFilterOperatorsDto.EqualsDto, value: null };
|
|
1377
|
-
case 'isnotnull':
|
|
1378
|
-
return { operator: FieldFilterOperatorsDto.NotEqualsDto, value: null };
|
|
1379
|
-
case 'isempty':
|
|
1380
|
-
return { operator: FieldFilterOperatorsDto.EqualsDto, value: "" };
|
|
1381
|
-
case 'isnotempty':
|
|
1382
|
-
return { operator: FieldFilterOperatorsDto.NotEqualsDto, value: "" };
|
|
1383
|
-
default:
|
|
1384
|
-
throw new Error('The filter operator is not supported');
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
class OctoGraphQlHierarchyDataSource extends HierarchyDataSourceBase {
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
913
|
/**
|
|
1393
914
|
* Component for displaying property values with appropriate formatting
|
|
1394
915
|
*/
|
|
@@ -1837,502 +1358,981 @@ class PropertyValueDisplayComponent {
|
|
|
1837
1358
|
</div>
|
|
1838
1359
|
}
|
|
1839
1360
|
</div>
|
|
1840
|
-
}
|
|
1841
|
-
</div>
|
|
1842
|
-
} @else if (isBinaryLinkedWithDownload()) {
|
|
1843
|
-
<!-- Binary Linked with download capability -->
|
|
1844
|
-
<div class="binary-linked-display">
|
|
1845
|
-
<div class="binary-info">
|
|
1846
|
-
@if (getBinaryFilename()) {
|
|
1847
|
-
<span class="filename">{{ getBinaryFilename() }}</span>
|
|
1848
|
-
}
|
|
1849
|
-
@if (getBinarySize()) {
|
|
1850
|
-
<span class="file-size">({{ formatFileSize(getBinarySize()) }})</span>
|
|
1851
|
-
}
|
|
1852
|
-
@if (getBinaryContentType()) {
|
|
1853
|
-
<span class="content-type">{{ getBinaryContentType() }}</span>
|
|
1854
|
-
}
|
|
1855
|
-
</div>
|
|
1856
|
-
<button
|
|
1857
|
-
kendoButton
|
|
1858
|
-
size="small"
|
|
1859
|
-
fillMode="flat"
|
|
1860
|
-
[svgIcon]="downloadIcon"
|
|
1861
|
-
title="Download file"
|
|
1862
|
-
(click)="onDownload()">
|
|
1863
|
-
Download
|
|
1864
|
-
</button>
|
|
1865
|
-
</div>
|
|
1866
|
-
} @else {
|
|
1867
|
-
<!-- Non-expandable value display -->
|
|
1868
|
-
@switch (displayMode) {
|
|
1869
|
-
@case (PropertyDisplayMode.Json) {
|
|
1870
|
-
<pre class="json-display">{{ getFormattedValue() }}</pre>
|
|
1871
|
-
}
|
|
1872
|
-
@case (PropertyDisplayMode.Text) {
|
|
1873
|
-
<span class="text-display" [innerHTML]="getFormattedValue()"></span>
|
|
1874
|
-
}
|
|
1875
|
-
@default {
|
|
1876
|
-
<span class="default-display">{{ getFormattedValue() }}</span>
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1361
|
+
}
|
|
1362
|
+
</div>
|
|
1363
|
+
} @else if (isBinaryLinkedWithDownload()) {
|
|
1364
|
+
<!-- Binary Linked with download capability -->
|
|
1365
|
+
<div class="binary-linked-display">
|
|
1366
|
+
<div class="binary-info">
|
|
1367
|
+
@if (getBinaryFilename()) {
|
|
1368
|
+
<span class="filename">{{ getBinaryFilename() }}</span>
|
|
1369
|
+
}
|
|
1370
|
+
@if (getBinarySize()) {
|
|
1371
|
+
<span class="file-size">({{ formatFileSize(getBinarySize()) }})</span>
|
|
1372
|
+
}
|
|
1373
|
+
@if (getBinaryContentType()) {
|
|
1374
|
+
<span class="content-type">{{ getBinaryContentType() }}</span>
|
|
1375
|
+
}
|
|
1376
|
+
</div>
|
|
1377
|
+
<button
|
|
1378
|
+
kendoButton
|
|
1379
|
+
size="small"
|
|
1380
|
+
fillMode="flat"
|
|
1381
|
+
[svgIcon]="downloadIcon"
|
|
1382
|
+
title="Download file"
|
|
1383
|
+
(click)="onDownload()">
|
|
1384
|
+
Download
|
|
1385
|
+
</button>
|
|
1386
|
+
</div>
|
|
1387
|
+
} @else {
|
|
1388
|
+
<!-- Non-expandable value display -->
|
|
1389
|
+
@switch (displayMode) {
|
|
1390
|
+
@case (PropertyDisplayMode.Json) {
|
|
1391
|
+
<pre class="json-display">{{ getFormattedValue() }}</pre>
|
|
1392
|
+
}
|
|
1393
|
+
@case (PropertyDisplayMode.Text) {
|
|
1394
|
+
<span class="text-display" [innerHTML]="getFormattedValue()"></span>
|
|
1395
|
+
}
|
|
1396
|
+
@default {
|
|
1397
|
+
<span class="default-display">{{ getFormattedValue() }}</span>
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
@if (isComplexType() && !isExpandableRecord()) {
|
|
1402
|
+
<span class="type-indicator" [title]="getTypeDescription()">
|
|
1403
|
+
{{ getTypeIndicator() }}
|
|
1404
|
+
</span>
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
</div>
|
|
1408
|
+
`, 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.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.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"] }] });
|
|
1409
|
+
}
|
|
1410
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PropertyValueDisplayComponent, decorators: [{
|
|
1411
|
+
type: Component,
|
|
1412
|
+
args: [{ selector: 'mm-property-value-display', standalone: true, imports: [CommonModule, SVGIconModule, ButtonModule], template: `
|
|
1413
|
+
<div class="property-value-display" [ngClass]="'type-' + type.toLowerCase()">
|
|
1414
|
+
|
|
1415
|
+
@if (isExpandableRecord()) {
|
|
1416
|
+
<div class="expandable-record">
|
|
1417
|
+
<!-- Expand/Collapse Button and Summary -->
|
|
1418
|
+
<div class="record-header" (click)="toggleExpansion()">
|
|
1419
|
+
<kendo-svgicon
|
|
1420
|
+
[icon]="isExpanded ? chevronDownIcon : chevronRightIcon"
|
|
1421
|
+
class="expand-icon">
|
|
1422
|
+
</kendo-svgicon>
|
|
1423
|
+
<span class="record-summary">{{ getRecordSummary() }}</span>
|
|
1424
|
+
<span class="type-indicator" [title]="getTypeDescription()">
|
|
1425
|
+
{{ getTypeIndicator() }}
|
|
1426
|
+
</span>
|
|
1427
|
+
</div>
|
|
1428
|
+
|
|
1429
|
+
<!-- Expanded Content -->
|
|
1430
|
+
@if (isExpanded) {
|
|
1431
|
+
<div class="record-content">
|
|
1432
|
+
@if (type === AttributeValueTypeDto.RecordArrayDto && Array.isArray(value)) {
|
|
1433
|
+
@for (item of value; track $index) {
|
|
1434
|
+
<div class="array-item">
|
|
1435
|
+
<span class="array-index">[{{ $index }}]</span>
|
|
1436
|
+
<div class="nested-properties">
|
|
1437
|
+
@for (prop of getObjectProperties(item); track prop.key) {
|
|
1438
|
+
<div class="nested-property">
|
|
1439
|
+
<span class="property-key">{{ prop.key }}:</span>
|
|
1440
|
+
<mm-property-value-display
|
|
1441
|
+
[value]="prop.value"
|
|
1442
|
+
[type]="getPropertyType(prop.value)">
|
|
1443
|
+
</mm-property-value-display>
|
|
1444
|
+
</div>
|
|
1445
|
+
}
|
|
1446
|
+
</div>
|
|
1447
|
+
</div>
|
|
1448
|
+
}
|
|
1449
|
+
} @else {
|
|
1450
|
+
<div class="nested-properties">
|
|
1451
|
+
@for (prop of getObjectProperties(value); track prop.key) {
|
|
1452
|
+
<div class="nested-property">
|
|
1453
|
+
<span class="property-key">{{ prop.key }}:</span>
|
|
1454
|
+
<mm-property-value-display
|
|
1455
|
+
[value]="prop.value"
|
|
1456
|
+
[type]="getPropertyType(prop.value)">
|
|
1457
|
+
</mm-property-value-display>
|
|
1458
|
+
</div>
|
|
1459
|
+
}
|
|
1460
|
+
</div>
|
|
1461
|
+
}
|
|
1462
|
+
</div>
|
|
1463
|
+
}
|
|
1464
|
+
</div>
|
|
1465
|
+
} @else if (isBinaryLinkedWithDownload()) {
|
|
1466
|
+
<!-- Binary Linked with download capability -->
|
|
1467
|
+
<div class="binary-linked-display">
|
|
1468
|
+
<div class="binary-info">
|
|
1469
|
+
@if (getBinaryFilename()) {
|
|
1470
|
+
<span class="filename">{{ getBinaryFilename() }}</span>
|
|
1471
|
+
}
|
|
1472
|
+
@if (getBinarySize()) {
|
|
1473
|
+
<span class="file-size">({{ formatFileSize(getBinarySize()) }})</span>
|
|
1474
|
+
}
|
|
1475
|
+
@if (getBinaryContentType()) {
|
|
1476
|
+
<span class="content-type">{{ getBinaryContentType() }}</span>
|
|
1477
|
+
}
|
|
1478
|
+
</div>
|
|
1479
|
+
<button
|
|
1480
|
+
kendoButton
|
|
1481
|
+
size="small"
|
|
1482
|
+
fillMode="flat"
|
|
1483
|
+
[svgIcon]="downloadIcon"
|
|
1484
|
+
title="Download file"
|
|
1485
|
+
(click)="onDownload()">
|
|
1486
|
+
Download
|
|
1487
|
+
</button>
|
|
1488
|
+
</div>
|
|
1489
|
+
} @else {
|
|
1490
|
+
<!-- Non-expandable value display -->
|
|
1491
|
+
@switch (displayMode) {
|
|
1492
|
+
@case (PropertyDisplayMode.Json) {
|
|
1493
|
+
<pre class="json-display">{{ getFormattedValue() }}</pre>
|
|
1494
|
+
}
|
|
1495
|
+
@case (PropertyDisplayMode.Text) {
|
|
1496
|
+
<span class="text-display" [innerHTML]="getFormattedValue()"></span>
|
|
1497
|
+
}
|
|
1498
|
+
@default {
|
|
1499
|
+
<span class="default-display">{{ getFormattedValue() }}</span>
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
@if (isComplexType() && !isExpandableRecord()) {
|
|
1504
|
+
<span class="type-indicator" [title]="getTypeDescription()">
|
|
1505
|
+
{{ getTypeIndicator() }}
|
|
1506
|
+
</span>
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
</div>
|
|
1510
|
+
`, 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"] }]
|
|
1511
|
+
}], propDecorators: { value: [{
|
|
1512
|
+
type: Input
|
|
1513
|
+
}], type: [{
|
|
1514
|
+
type: Input
|
|
1515
|
+
}], displayMode: [{
|
|
1516
|
+
type: Input
|
|
1517
|
+
}], binaryDownload: [{
|
|
1518
|
+
type: Output
|
|
1519
|
+
}] } });
|
|
1520
|
+
|
|
1521
|
+
/**
|
|
1522
|
+
* Generic property grid component for OctoMesh
|
|
1523
|
+
*/
|
|
1524
|
+
class PropertyGridComponent {
|
|
1525
|
+
data = [];
|
|
1526
|
+
config = {};
|
|
1527
|
+
showTypeColumn = false;
|
|
1528
|
+
propertyChange = new EventEmitter();
|
|
1529
|
+
saveRequested = new EventEmitter();
|
|
1530
|
+
binaryDownload = new EventEmitter();
|
|
1531
|
+
// Component state
|
|
1532
|
+
filteredData = [];
|
|
1533
|
+
searchTerm = '';
|
|
1534
|
+
hasChanges = false;
|
|
1535
|
+
pendingChanges = [];
|
|
1536
|
+
// Icons
|
|
1537
|
+
fileIcon = fileIcon;
|
|
1538
|
+
folderIcon = folderIcon;
|
|
1539
|
+
calendarIcon = calendarIcon;
|
|
1540
|
+
checkboxCheckedIcon = checkboxCheckedIcon;
|
|
1541
|
+
listUnorderedIcon = listUnorderedIcon;
|
|
1542
|
+
// Enum reference
|
|
1543
|
+
AttributeValueTypeDto = AttributeValueTypeDto;
|
|
1544
|
+
ngOnInit() {
|
|
1545
|
+
this.updateFilteredData();
|
|
1546
|
+
}
|
|
1547
|
+
ngOnChanges(changes) {
|
|
1548
|
+
if (changes['data']) {
|
|
1549
|
+
this.updateFilteredData();
|
|
1550
|
+
this.hasChanges = false;
|
|
1551
|
+
this.pendingChanges = [];
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
get gridHeight() {
|
|
1555
|
+
const baseHeight = this.config.height || '400px';
|
|
1556
|
+
const searchHeight = this.config.showSearch ? 40 : 0;
|
|
1557
|
+
const toolbarHeight = !this.config.readOnlyMode ? 50 : 0;
|
|
1558
|
+
const totalOffset = searchHeight + toolbarHeight;
|
|
1559
|
+
if (baseHeight.includes('px')) {
|
|
1560
|
+
const px = parseInt(baseHeight) - totalOffset;
|
|
1561
|
+
return `${Math.max(px, 200)}px`;
|
|
1562
|
+
}
|
|
1563
|
+
return baseHeight;
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Update filtered data based on search term
|
|
1567
|
+
*/
|
|
1568
|
+
updateFilteredData() {
|
|
1569
|
+
if (!this.searchTerm.trim()) {
|
|
1570
|
+
this.filteredData = [...this.data];
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
const term = this.searchTerm.toLowerCase();
|
|
1574
|
+
this.filteredData = this.data.filter(item => item.name.toLowerCase().includes(term) ||
|
|
1575
|
+
(item.displayName?.toLowerCase().includes(term)) ||
|
|
1576
|
+
(item.description?.toLowerCase().includes(term)) ||
|
|
1577
|
+
String(item.value).toLowerCase().includes(term));
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* Handle search input
|
|
1581
|
+
*/
|
|
1582
|
+
onSearch() {
|
|
1583
|
+
this.updateFilteredData();
|
|
1584
|
+
}
|
|
1585
|
+
/**
|
|
1586
|
+
* Get appropriate icon for property type
|
|
1587
|
+
*/
|
|
1588
|
+
getTypeIcon(type) {
|
|
1589
|
+
switch (type) {
|
|
1590
|
+
case AttributeValueTypeDto.BooleanDto:
|
|
1591
|
+
return checkboxCheckedIcon;
|
|
1592
|
+
case AttributeValueTypeDto.IntDto:
|
|
1593
|
+
case AttributeValueTypeDto.IntegerDto:
|
|
1594
|
+
case AttributeValueTypeDto.DoubleDto:
|
|
1595
|
+
return fileIcon;
|
|
1596
|
+
case AttributeValueTypeDto.DateTimeDto:
|
|
1597
|
+
case AttributeValueTypeDto.DateTimeOffsetDto:
|
|
1598
|
+
return calendarIcon;
|
|
1599
|
+
case AttributeValueTypeDto.StringArrayDto:
|
|
1600
|
+
case AttributeValueTypeDto.IntegerArrayDto:
|
|
1601
|
+
return listUnorderedIcon;
|
|
1602
|
+
case AttributeValueTypeDto.RecordDto:
|
|
1603
|
+
case AttributeValueTypeDto.RecordArrayDto:
|
|
1604
|
+
return folderIcon;
|
|
1605
|
+
default:
|
|
1606
|
+
return fileIcon;
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
/**
|
|
1610
|
+
* Format type name for display
|
|
1611
|
+
*/
|
|
1612
|
+
formatTypeName(type) {
|
|
1613
|
+
return type.replace('_DTO', '').replace('DTO', '').replace('_', ' ');
|
|
1614
|
+
}
|
|
1615
|
+
/**
|
|
1616
|
+
* Save pending changes
|
|
1617
|
+
*/
|
|
1618
|
+
saveChanges() {
|
|
1619
|
+
if (this.pendingChanges.length > 0) {
|
|
1620
|
+
const updatedData = this.data.map(item => {
|
|
1621
|
+
const change = this.pendingChanges.find(c => c.property.id === item.id);
|
|
1622
|
+
return change ? { ...item, value: change.newValue } : item;
|
|
1623
|
+
});
|
|
1624
|
+
this.saveRequested.emit(updatedData);
|
|
1625
|
+
this.hasChanges = false;
|
|
1626
|
+
this.pendingChanges = [];
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Discard pending changes
|
|
1631
|
+
*/
|
|
1632
|
+
discardChanges() {
|
|
1633
|
+
this.hasChanges = false;
|
|
1634
|
+
this.pendingChanges = [];
|
|
1635
|
+
this.updateFilteredData();
|
|
1636
|
+
}
|
|
1637
|
+
/**
|
|
1638
|
+
* Handle property value change
|
|
1639
|
+
*/
|
|
1640
|
+
onPropertyChange(property, oldValue, newValue) {
|
|
1641
|
+
const changeEvent = {
|
|
1642
|
+
property,
|
|
1643
|
+
oldValue,
|
|
1644
|
+
newValue
|
|
1645
|
+
};
|
|
1646
|
+
// Update or add to pending changes
|
|
1647
|
+
const existingIndex = this.pendingChanges.findIndex(c => c.property.id === property.id);
|
|
1648
|
+
if (existingIndex >= 0) {
|
|
1649
|
+
this.pendingChanges[existingIndex] = changeEvent;
|
|
1650
|
+
}
|
|
1651
|
+
else {
|
|
1652
|
+
this.pendingChanges.push(changeEvent);
|
|
1653
|
+
}
|
|
1654
|
+
this.hasChanges = this.pendingChanges.length > 0;
|
|
1655
|
+
this.propertyChange.emit(changeEvent);
|
|
1656
|
+
}
|
|
1657
|
+
/**
|
|
1658
|
+
* Handle binary download request from property value display
|
|
1659
|
+
*/
|
|
1660
|
+
onBinaryDownload(event) {
|
|
1661
|
+
this.binaryDownload.emit(event);
|
|
1662
|
+
}
|
|
1663
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PropertyGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1664
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.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: `
|
|
1665
|
+
<div class="mm-property-grid" [style.height]="config.height || '400px'">
|
|
1666
|
+
|
|
1667
|
+
@if (config.showSearch) {
|
|
1668
|
+
<div class="search-toolbar">
|
|
1669
|
+
<kendo-textbox
|
|
1670
|
+
[(ngModel)]="searchTerm"
|
|
1671
|
+
placeholder="Search attributes..."
|
|
1672
|
+
(input)="onSearch()"
|
|
1673
|
+
[clearButton]="true">
|
|
1674
|
+
</kendo-textbox>
|
|
1675
|
+
</div>
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
<kendo-grid
|
|
1679
|
+
[data]="filteredData"
|
|
1680
|
+
[sortable]="true"
|
|
1681
|
+
[resizable]="true"
|
|
1682
|
+
[style.height]="gridHeight"
|
|
1683
|
+
[selectable]="{mode: 'single'}"
|
|
1684
|
+
class="property-grid">
|
|
1685
|
+
|
|
1686
|
+
<!-- Property Name Column -->
|
|
1687
|
+
<kendo-grid-column
|
|
1688
|
+
field="displayName"
|
|
1689
|
+
title="Property"
|
|
1690
|
+
[width]="200"
|
|
1691
|
+
[sortable]="true">
|
|
1692
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1693
|
+
<div class="property-name-cell">
|
|
1694
|
+
@if (config.showTypeIcons !== false) {
|
|
1695
|
+
<kendo-svgicon
|
|
1696
|
+
[icon]="getTypeIcon(dataItem.type)"
|
|
1697
|
+
class="type-icon">
|
|
1698
|
+
</kendo-svgicon>
|
|
1699
|
+
}
|
|
1700
|
+
<div class="property-info">
|
|
1701
|
+
<span class="property-name" [title]="dataItem.description">
|
|
1702
|
+
{{ dataItem.displayName || dataItem.name }}
|
|
1703
|
+
</span>
|
|
1704
|
+
@if (dataItem.required) {
|
|
1705
|
+
<span class="required-indicator">*</span>
|
|
1706
|
+
}
|
|
1707
|
+
@if (dataItem.readOnly) {
|
|
1708
|
+
<span class="readonly-indicator" title="Read-only">🔒</span>
|
|
1709
|
+
}
|
|
1710
|
+
</div>
|
|
1711
|
+
</div>
|
|
1712
|
+
</ng-template>
|
|
1713
|
+
</kendo-grid-column>
|
|
1879
1714
|
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1715
|
+
<!-- Property Value Column -->
|
|
1716
|
+
<kendo-grid-column
|
|
1717
|
+
field="value"
|
|
1718
|
+
title="Value"
|
|
1719
|
+
[sortable]="false">
|
|
1720
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1721
|
+
<mm-property-value-display
|
|
1722
|
+
[value]="dataItem.value"
|
|
1723
|
+
[type]="dataItem.type"
|
|
1724
|
+
(binaryDownload)="onBinaryDownload($event)">
|
|
1725
|
+
</mm-property-value-display>
|
|
1726
|
+
</ng-template>
|
|
1727
|
+
</kendo-grid-column>
|
|
1728
|
+
|
|
1729
|
+
<!-- Type Column (optional) -->
|
|
1730
|
+
@if (showTypeColumn) {
|
|
1731
|
+
<kendo-grid-column
|
|
1732
|
+
field="type"
|
|
1733
|
+
title="Type"
|
|
1734
|
+
[width]="120"
|
|
1735
|
+
[sortable]="true">
|
|
1736
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1737
|
+
<span class="type-badge" [ngClass]="'type-' + dataItem.type.toLowerCase()">
|
|
1738
|
+
{{ formatTypeName(dataItem.type) }}
|
|
1739
|
+
</span>
|
|
1740
|
+
</ng-template>
|
|
1741
|
+
</kendo-grid-column>
|
|
1884
1742
|
}
|
|
1885
|
-
|
|
1743
|
+
|
|
1744
|
+
</kendo-grid>
|
|
1886
1745
|
</div>
|
|
1887
|
-
`, isInline: true, styles: [".property-
|
|
1746
|
+
`, 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.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i2$1.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: i2$1.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i2$1.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: InputsModule }, { kind: "component", type: i4.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"] }] });
|
|
1888
1747
|
}
|
|
1889
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type:
|
|
1748
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PropertyGridComponent, decorators: [{
|
|
1890
1749
|
type: Component,
|
|
1891
|
-
args: [{ selector: 'mm-property-
|
|
1892
|
-
|
|
1750
|
+
args: [{ selector: 'mm-property-grid', standalone: true, imports: [
|
|
1751
|
+
CommonModule,
|
|
1752
|
+
FormsModule,
|
|
1753
|
+
GridModule,
|
|
1754
|
+
InputsModule,
|
|
1755
|
+
DropDownsModule,
|
|
1756
|
+
ButtonsModule,
|
|
1757
|
+
SVGIconModule,
|
|
1758
|
+
PropertyValueDisplayComponent
|
|
1759
|
+
], template: `
|
|
1760
|
+
<div class="mm-property-grid" [style.height]="config.height || '400px'">
|
|
1893
1761
|
|
|
1894
|
-
@if (
|
|
1895
|
-
<div class="
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
{{ getTypeIndicator() }}
|
|
1905
|
-
</span>
|
|
1906
|
-
</div>
|
|
1762
|
+
@if (config.showSearch) {
|
|
1763
|
+
<div class="search-toolbar">
|
|
1764
|
+
<kendo-textbox
|
|
1765
|
+
[(ngModel)]="searchTerm"
|
|
1766
|
+
placeholder="Search attributes..."
|
|
1767
|
+
(input)="onSearch()"
|
|
1768
|
+
[clearButton]="true">
|
|
1769
|
+
</kendo-textbox>
|
|
1770
|
+
</div>
|
|
1771
|
+
}
|
|
1907
1772
|
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
<div class="nested-properties">
|
|
1930
|
-
@for (prop of getObjectProperties(value); track prop.key) {
|
|
1931
|
-
<div class="nested-property">
|
|
1932
|
-
<span class="property-key">{{ prop.key }}:</span>
|
|
1933
|
-
<mm-property-value-display
|
|
1934
|
-
[value]="prop.value"
|
|
1935
|
-
[type]="getPropertyType(prop.value)">
|
|
1936
|
-
</mm-property-value-display>
|
|
1937
|
-
</div>
|
|
1938
|
-
}
|
|
1939
|
-
</div>
|
|
1773
|
+
<kendo-grid
|
|
1774
|
+
[data]="filteredData"
|
|
1775
|
+
[sortable]="true"
|
|
1776
|
+
[resizable]="true"
|
|
1777
|
+
[style.height]="gridHeight"
|
|
1778
|
+
[selectable]="{mode: 'single'}"
|
|
1779
|
+
class="property-grid">
|
|
1780
|
+
|
|
1781
|
+
<!-- Property Name Column -->
|
|
1782
|
+
<kendo-grid-column
|
|
1783
|
+
field="displayName"
|
|
1784
|
+
title="Property"
|
|
1785
|
+
[width]="200"
|
|
1786
|
+
[sortable]="true">
|
|
1787
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1788
|
+
<div class="property-name-cell">
|
|
1789
|
+
@if (config.showTypeIcons !== false) {
|
|
1790
|
+
<kendo-svgicon
|
|
1791
|
+
[icon]="getTypeIcon(dataItem.type)"
|
|
1792
|
+
class="type-icon">
|
|
1793
|
+
</kendo-svgicon>
|
|
1940
1794
|
}
|
|
1795
|
+
<div class="property-info">
|
|
1796
|
+
<span class="property-name" [title]="dataItem.description">
|
|
1797
|
+
{{ dataItem.displayName || dataItem.name }}
|
|
1798
|
+
</span>
|
|
1799
|
+
@if (dataItem.required) {
|
|
1800
|
+
<span class="required-indicator">*</span>
|
|
1801
|
+
}
|
|
1802
|
+
@if (dataItem.readOnly) {
|
|
1803
|
+
<span class="readonly-indicator" title="Read-only">🔒</span>
|
|
1804
|
+
}
|
|
1805
|
+
</div>
|
|
1941
1806
|
</div>
|
|
1942
|
-
|
|
1943
|
-
</
|
|
1944
|
-
} @else if (isBinaryLinkedWithDownload()) {
|
|
1945
|
-
<!-- Binary Linked with download capability -->
|
|
1946
|
-
<div class="binary-linked-display">
|
|
1947
|
-
<div class="binary-info">
|
|
1948
|
-
@if (getBinaryFilename()) {
|
|
1949
|
-
<span class="filename">{{ getBinaryFilename() }}</span>
|
|
1950
|
-
}
|
|
1951
|
-
@if (getBinarySize()) {
|
|
1952
|
-
<span class="file-size">({{ formatFileSize(getBinarySize()) }})</span>
|
|
1953
|
-
}
|
|
1954
|
-
@if (getBinaryContentType()) {
|
|
1955
|
-
<span class="content-type">{{ getBinaryContentType() }}</span>
|
|
1956
|
-
}
|
|
1957
|
-
</div>
|
|
1958
|
-
<button
|
|
1959
|
-
kendoButton
|
|
1960
|
-
size="small"
|
|
1961
|
-
fillMode="flat"
|
|
1962
|
-
[svgIcon]="downloadIcon"
|
|
1963
|
-
title="Download file"
|
|
1964
|
-
(click)="onDownload()">
|
|
1965
|
-
Download
|
|
1966
|
-
</button>
|
|
1967
|
-
</div>
|
|
1968
|
-
} @else {
|
|
1969
|
-
<!-- Non-expandable value display -->
|
|
1970
|
-
@switch (displayMode) {
|
|
1971
|
-
@case (PropertyDisplayMode.Json) {
|
|
1972
|
-
<pre class="json-display">{{ getFormattedValue() }}</pre>
|
|
1973
|
-
}
|
|
1974
|
-
@case (PropertyDisplayMode.Text) {
|
|
1975
|
-
<span class="text-display" [innerHTML]="getFormattedValue()"></span>
|
|
1976
|
-
}
|
|
1977
|
-
@default {
|
|
1978
|
-
<span class="default-display">{{ getFormattedValue() }}</span>
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1807
|
+
</ng-template>
|
|
1808
|
+
</kendo-grid-column>
|
|
1981
1809
|
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1810
|
+
<!-- Property Value Column -->
|
|
1811
|
+
<kendo-grid-column
|
|
1812
|
+
field="value"
|
|
1813
|
+
title="Value"
|
|
1814
|
+
[sortable]="false">
|
|
1815
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1816
|
+
<mm-property-value-display
|
|
1817
|
+
[value]="dataItem.value"
|
|
1818
|
+
[type]="dataItem.type"
|
|
1819
|
+
(binaryDownload)="onBinaryDownload($event)">
|
|
1820
|
+
</mm-property-value-display>
|
|
1821
|
+
</ng-template>
|
|
1822
|
+
</kendo-grid-column>
|
|
1823
|
+
|
|
1824
|
+
<!-- Type Column (optional) -->
|
|
1825
|
+
@if (showTypeColumn) {
|
|
1826
|
+
<kendo-grid-column
|
|
1827
|
+
field="type"
|
|
1828
|
+
title="Type"
|
|
1829
|
+
[width]="120"
|
|
1830
|
+
[sortable]="true">
|
|
1831
|
+
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
1832
|
+
<span class="type-badge" [ngClass]="'type-' + dataItem.type.toLowerCase()">
|
|
1833
|
+
{{ formatTypeName(dataItem.type) }}
|
|
1834
|
+
</span>
|
|
1835
|
+
</ng-template>
|
|
1836
|
+
</kendo-grid-column>
|
|
1986
1837
|
}
|
|
1987
|
-
|
|
1838
|
+
|
|
1839
|
+
</kendo-grid>
|
|
1988
1840
|
</div>
|
|
1989
|
-
`, styles: [".property-
|
|
1990
|
-
}], propDecorators: {
|
|
1841
|
+
`, 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"] }]
|
|
1842
|
+
}], propDecorators: { data: [{
|
|
1991
1843
|
type: Input
|
|
1992
|
-
}],
|
|
1844
|
+
}], config: [{
|
|
1993
1845
|
type: Input
|
|
1994
|
-
}],
|
|
1846
|
+
}], showTypeColumn: [{
|
|
1995
1847
|
type: Input
|
|
1848
|
+
}], propertyChange: [{
|
|
1849
|
+
type: Output
|
|
1850
|
+
}], saveRequested: [{
|
|
1851
|
+
type: Output
|
|
1996
1852
|
}], binaryDownload: [{
|
|
1997
1853
|
type: Output
|
|
1998
1854
|
}] } });
|
|
1999
1855
|
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
this.updateFilteredData();
|
|
1856
|
+
// Models
|
|
1857
|
+
|
|
1858
|
+
class CkTypeSelectorDialogComponent extends DialogContentBase {
|
|
1859
|
+
ckTypeSelectorService = inject(CkTypeSelectorService);
|
|
1860
|
+
searchSubject = new Subject();
|
|
1861
|
+
subscriptions = new Subscription();
|
|
1862
|
+
searchIcon = searchIcon;
|
|
1863
|
+
filterClearIcon = filterClearIcon;
|
|
1864
|
+
dialogTitle = 'Select Construction Kit Type';
|
|
1865
|
+
allowAbstract = false;
|
|
1866
|
+
searchText = '';
|
|
1867
|
+
selectedModel = null;
|
|
1868
|
+
availableModels = [];
|
|
1869
|
+
gridData = { data: [], total: 0 };
|
|
1870
|
+
isLoading = false;
|
|
1871
|
+
pageSize = 50;
|
|
1872
|
+
skip = 0;
|
|
1873
|
+
selectedKeys = [];
|
|
1874
|
+
selectedType = null;
|
|
1875
|
+
// Selection key function - returns fullName as unique identifier
|
|
1876
|
+
selectItemBy = (context) => context.dataItem.fullName;
|
|
1877
|
+
initialCkModelIds;
|
|
1878
|
+
constructor() {
|
|
1879
|
+
super(inject(DialogRef));
|
|
2025
1880
|
}
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
this.
|
|
2030
|
-
this.
|
|
1881
|
+
ngOnInit() {
|
|
1882
|
+
const data = this.dialog.content?.instance?.data;
|
|
1883
|
+
if (data) {
|
|
1884
|
+
this.dialogTitle = data.dialogTitle || 'Select Construction Kit Type';
|
|
1885
|
+
this.allowAbstract = data.allowAbstract ?? false;
|
|
1886
|
+
this.initialCkModelIds = data.ckModelIds;
|
|
1887
|
+
if (data.selectedCkTypeId) {
|
|
1888
|
+
this.selectedKeys = [data.selectedCkTypeId];
|
|
1889
|
+
}
|
|
2031
1890
|
}
|
|
1891
|
+
// Set up search debouncing
|
|
1892
|
+
this.subscriptions.add(this.searchSubject.pipe(debounceTime(300), distinctUntilChanged()).subscribe(() => {
|
|
1893
|
+
this.skip = 0;
|
|
1894
|
+
this.loadTypes();
|
|
1895
|
+
}));
|
|
1896
|
+
// Load initial types and extract available models
|
|
1897
|
+
this.loadTypes();
|
|
1898
|
+
this.loadAvailableModels();
|
|
2032
1899
|
}
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
const searchHeight = this.config.showSearch ? 40 : 0;
|
|
2036
|
-
const toolbarHeight = !this.config.readOnlyMode ? 50 : 0;
|
|
2037
|
-
const totalOffset = searchHeight + toolbarHeight;
|
|
2038
|
-
if (baseHeight.includes('px')) {
|
|
2039
|
-
const px = parseInt(baseHeight) - totalOffset;
|
|
2040
|
-
return `${Math.max(px, 200)}px`;
|
|
2041
|
-
}
|
|
2042
|
-
return baseHeight;
|
|
1900
|
+
ngOnDestroy() {
|
|
1901
|
+
this.subscriptions.unsubscribe();
|
|
2043
1902
|
}
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
1903
|
+
loadTypes() {
|
|
1904
|
+
this.isLoading = true;
|
|
1905
|
+
const ckModelIds = this.selectedModel
|
|
1906
|
+
? [this.selectedModel]
|
|
1907
|
+
: this.initialCkModelIds;
|
|
1908
|
+
this.subscriptions.add(this.ckTypeSelectorService.getCkTypes({
|
|
1909
|
+
ckModelIds,
|
|
1910
|
+
searchText: this.searchText || undefined,
|
|
1911
|
+
first: this.pageSize,
|
|
1912
|
+
skip: this.skip
|
|
1913
|
+
}).subscribe({
|
|
1914
|
+
next: result => {
|
|
1915
|
+
this.gridData = {
|
|
1916
|
+
data: result.items,
|
|
1917
|
+
total: result.totalCount
|
|
1918
|
+
};
|
|
1919
|
+
// Restore selection if exists
|
|
1920
|
+
if (this.selectedKeys.length > 0) {
|
|
1921
|
+
const selectedItem = result.items.find(item => item.fullName === this.selectedKeys[0]);
|
|
1922
|
+
if (selectedItem) {
|
|
1923
|
+
this.selectedType = selectedItem;
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
this.isLoading = false;
|
|
1927
|
+
},
|
|
1928
|
+
error: () => {
|
|
1929
|
+
this.isLoading = false;
|
|
1930
|
+
this.gridData = { data: [], total: 0 };
|
|
1931
|
+
}
|
|
1932
|
+
}));
|
|
2057
1933
|
}
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
1934
|
+
loadAvailableModels() {
|
|
1935
|
+
// Load all types to extract unique models
|
|
1936
|
+
this.subscriptions.add(this.ckTypeSelectorService.getCkTypes({
|
|
1937
|
+
first: 1000
|
|
1938
|
+
}).subscribe(result => {
|
|
1939
|
+
const modelSet = new Set();
|
|
1940
|
+
result.items.forEach(item => {
|
|
1941
|
+
// Extract model from fullName (format: "ModelName-Version/TypeName-Version")
|
|
1942
|
+
const modelMatch = item.fullName.match(/^([^/]+)\//);
|
|
1943
|
+
if (modelMatch) {
|
|
1944
|
+
modelSet.add(modelMatch[1]);
|
|
1945
|
+
}
|
|
1946
|
+
});
|
|
1947
|
+
this.availableModels = Array.from(modelSet).sort();
|
|
1948
|
+
}));
|
|
2063
1949
|
}
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
*/
|
|
2067
|
-
getTypeIcon(type) {
|
|
2068
|
-
switch (type) {
|
|
2069
|
-
case AttributeValueTypeDto.BooleanDto:
|
|
2070
|
-
return checkboxCheckedIcon;
|
|
2071
|
-
case AttributeValueTypeDto.IntDto:
|
|
2072
|
-
case AttributeValueTypeDto.IntegerDto:
|
|
2073
|
-
case AttributeValueTypeDto.DoubleDto:
|
|
2074
|
-
return fileIcon;
|
|
2075
|
-
case AttributeValueTypeDto.DateTimeDto:
|
|
2076
|
-
case AttributeValueTypeDto.DateTimeOffsetDto:
|
|
2077
|
-
return calendarIcon;
|
|
2078
|
-
case AttributeValueTypeDto.StringArrayDto:
|
|
2079
|
-
case AttributeValueTypeDto.IntegerArrayDto:
|
|
2080
|
-
return listUnorderedIcon;
|
|
2081
|
-
case AttributeValueTypeDto.RecordDto:
|
|
2082
|
-
case AttributeValueTypeDto.RecordArrayDto:
|
|
2083
|
-
return folderIcon;
|
|
2084
|
-
default:
|
|
2085
|
-
return fileIcon;
|
|
2086
|
-
}
|
|
1950
|
+
onSearchChange(value) {
|
|
1951
|
+
this.searchSubject.next(value);
|
|
2087
1952
|
}
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
formatTypeName(type) {
|
|
2092
|
-
return type.replace('_DTO', '').replace('DTO', '').replace('_', ' ');
|
|
1953
|
+
onModelFilterChange(_value) {
|
|
1954
|
+
this.skip = 0;
|
|
1955
|
+
this.loadTypes();
|
|
2093
1956
|
}
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
const updatedData = this.data.map(item => {
|
|
2100
|
-
const change = this.pendingChanges.find(c => c.property.id === item.id);
|
|
2101
|
-
return change ? { ...item, value: change.newValue } : item;
|
|
2102
|
-
});
|
|
2103
|
-
this.saveRequested.emit(updatedData);
|
|
2104
|
-
this.hasChanges = false;
|
|
2105
|
-
this.pendingChanges = [];
|
|
2106
|
-
}
|
|
1957
|
+
clearFilters() {
|
|
1958
|
+
this.searchText = '';
|
|
1959
|
+
this.selectedModel = null;
|
|
1960
|
+
this.skip = 0;
|
|
1961
|
+
this.loadTypes();
|
|
2107
1962
|
}
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
this.hasChanges = false;
|
|
2113
|
-
this.pendingChanges = [];
|
|
2114
|
-
this.updateFilteredData();
|
|
1963
|
+
onPageChange(event) {
|
|
1964
|
+
this.skip = event.skip;
|
|
1965
|
+
this.pageSize = event.take;
|
|
1966
|
+
this.loadTypes();
|
|
2115
1967
|
}
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
const changeEvent = {
|
|
2121
|
-
property,
|
|
2122
|
-
oldValue,
|
|
2123
|
-
newValue
|
|
2124
|
-
};
|
|
2125
|
-
// Update or add to pending changes
|
|
2126
|
-
const existingIndex = this.pendingChanges.findIndex(c => c.property.id === property.id);
|
|
2127
|
-
if (existingIndex >= 0) {
|
|
2128
|
-
this.pendingChanges[existingIndex] = changeEvent;
|
|
1968
|
+
onSelectionChange(event) {
|
|
1969
|
+
const selectedItems = event.selectedRows;
|
|
1970
|
+
if (selectedItems && selectedItems.length > 0) {
|
|
1971
|
+
this.selectedType = selectedItems[0].dataItem;
|
|
2129
1972
|
}
|
|
2130
1973
|
else {
|
|
2131
|
-
this.
|
|
1974
|
+
this.selectedType = null;
|
|
2132
1975
|
}
|
|
2133
|
-
this.hasChanges = this.pendingChanges.length > 0;
|
|
2134
|
-
this.propertyChange.emit(changeEvent);
|
|
2135
1976
|
}
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
this.
|
|
1977
|
+
onCancel() {
|
|
1978
|
+
this.dialog.close();
|
|
1979
|
+
}
|
|
1980
|
+
onConfirm() {
|
|
1981
|
+
if (this.selectedType) {
|
|
1982
|
+
const result = {
|
|
1983
|
+
selectedCkType: this.selectedType
|
|
1984
|
+
};
|
|
1985
|
+
this.dialog.close(result);
|
|
1986
|
+
}
|
|
2141
1987
|
}
|
|
2142
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type:
|
|
2143
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2144
|
-
<div class="
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
1988
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1989
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.5", type: CkTypeSelectorDialogComponent, isStandalone: true, selector: "mm-ck-type-selector-dialog", usesInheritance: true, ngImport: i0, template: `
|
|
1990
|
+
<div class="ck-type-selector-container">
|
|
1991
|
+
<div class="filter-container">
|
|
1992
|
+
<div class="filter-row">
|
|
1993
|
+
<div class="filter-item">
|
|
1994
|
+
<label>Model Filter</label>
|
|
1995
|
+
<kendo-combobox
|
|
1996
|
+
[data]="availableModels"
|
|
1997
|
+
[(ngModel)]="selectedModel"
|
|
1998
|
+
(valueChange)="onModelFilterChange($event)"
|
|
1999
|
+
[allowCustom]="false"
|
|
2000
|
+
[clearButton]="true"
|
|
2001
|
+
placeholder="All Models"
|
|
2002
|
+
class="filter-input">
|
|
2003
|
+
</kendo-combobox>
|
|
2004
|
+
</div>
|
|
2005
|
+
<div class="filter-item flex-grow">
|
|
2006
|
+
<label>Type Search</label>
|
|
2007
|
+
<kendo-textbox
|
|
2008
|
+
[(ngModel)]="searchText"
|
|
2009
|
+
(ngModelChange)="onSearchChange($event)"
|
|
2010
|
+
placeholder="Search types..."
|
|
2011
|
+
class="filter-input">
|
|
2012
|
+
<ng-template kendoTextBoxSuffixTemplate>
|
|
2013
|
+
<button kendoButton [svgIcon]="searchIcon" fillMode="clear" size="small"></button>
|
|
2014
|
+
</ng-template>
|
|
2015
|
+
</kendo-textbox>
|
|
2016
|
+
</div>
|
|
2017
|
+
<div class="filter-item filter-actions">
|
|
2018
|
+
<label> </label>
|
|
2019
|
+
<button kendoButton [svgIcon]="filterClearIcon" (click)="clearFilters()" title="Clear filters"></button>
|
|
2020
|
+
</div>
|
|
2154
2021
|
</div>
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
<kendo-grid
|
|
2158
|
-
[data]="filteredData"
|
|
2159
|
-
[sortable]="true"
|
|
2160
|
-
[resizable]="true"
|
|
2161
|
-
[style.height]="gridHeight"
|
|
2162
|
-
[selectable]="{mode: 'single'}"
|
|
2163
|
-
class="property-grid">
|
|
2164
|
-
|
|
2165
|
-
<!-- Property Name Column -->
|
|
2166
|
-
<kendo-grid-column
|
|
2167
|
-
field="displayName"
|
|
2168
|
-
title="Property"
|
|
2169
|
-
[width]="200"
|
|
2170
|
-
[sortable]="true">
|
|
2171
|
-
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
2172
|
-
<div class="property-name-cell">
|
|
2173
|
-
@if (config.showTypeIcons !== false) {
|
|
2174
|
-
<kendo-svgicon
|
|
2175
|
-
[icon]="getTypeIcon(dataItem.type)"
|
|
2176
|
-
class="type-icon">
|
|
2177
|
-
</kendo-svgicon>
|
|
2178
|
-
}
|
|
2179
|
-
<div class="property-info">
|
|
2180
|
-
<span class="property-name" [title]="dataItem.description">
|
|
2181
|
-
{{ dataItem.displayName || dataItem.name }}
|
|
2182
|
-
</span>
|
|
2183
|
-
@if (dataItem.required) {
|
|
2184
|
-
<span class="required-indicator">*</span>
|
|
2185
|
-
}
|
|
2186
|
-
@if (dataItem.readOnly) {
|
|
2187
|
-
<span class="readonly-indicator" title="Read-only">🔒</span>
|
|
2188
|
-
}
|
|
2189
|
-
</div>
|
|
2190
|
-
</div>
|
|
2191
|
-
</ng-template>
|
|
2192
|
-
</kendo-grid-column>
|
|
2193
|
-
|
|
2194
|
-
<!-- Property Value Column -->
|
|
2195
|
-
<kendo-grid-column
|
|
2196
|
-
field="value"
|
|
2197
|
-
title="Value"
|
|
2198
|
-
[sortable]="false">
|
|
2199
|
-
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
2200
|
-
<mm-property-value-display
|
|
2201
|
-
[value]="dataItem.value"
|
|
2202
|
-
[type]="dataItem.type"
|
|
2203
|
-
(binaryDownload)="onBinaryDownload($event)">
|
|
2204
|
-
</mm-property-value-display>
|
|
2205
|
-
</ng-template>
|
|
2206
|
-
</kendo-grid-column>
|
|
2022
|
+
</div>
|
|
2207
2023
|
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2024
|
+
<div class="grid-container">
|
|
2025
|
+
<kendo-grid
|
|
2026
|
+
[data]="gridData"
|
|
2027
|
+
[loading]="isLoading"
|
|
2028
|
+
[height]="400"
|
|
2029
|
+
[selectable]="{ mode: 'single' }"
|
|
2030
|
+
[pageable]="{ pageSizes: [25, 50, 100] }"
|
|
2031
|
+
[pageSize]="pageSize"
|
|
2032
|
+
[skip]="skip"
|
|
2033
|
+
(pageChange)="onPageChange($event)"
|
|
2034
|
+
(selectionChange)="onSelectionChange($event)"
|
|
2035
|
+
[kendoGridSelectBy]="selectItemBy"
|
|
2036
|
+
[(selectedKeys)]="selectedKeys"
|
|
2037
|
+
class="type-grid">
|
|
2038
|
+
<kendo-grid-column field="rtCkTypeId" title="Type" [width]="300">
|
|
2039
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
2040
|
+
<span [class.abstract-type]="dataItem.isAbstract" [class.final-type]="dataItem.isFinal">
|
|
2041
|
+
{{ dataItem.rtCkTypeId }}
|
|
2218
2042
|
</span>
|
|
2043
|
+
<span *ngIf="dataItem.isAbstract" class="type-badge abstract">abstract</span>
|
|
2044
|
+
<span *ngIf="dataItem.isFinal" class="type-badge final">final</span>
|
|
2219
2045
|
</ng-template>
|
|
2220
2046
|
</kendo-grid-column>
|
|
2221
|
-
|
|
2047
|
+
<kendo-grid-column field="baseTypeRtCkTypeId" title="Base Type" [width]="200">
|
|
2048
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
2049
|
+
{{ dataItem.baseTypeRtCkTypeId || '-' }}
|
|
2050
|
+
</ng-template>
|
|
2051
|
+
</kendo-grid-column>
|
|
2052
|
+
<kendo-grid-column field="description" title="Description">
|
|
2053
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
2054
|
+
{{ dataItem.description || '-' }}
|
|
2055
|
+
</ng-template>
|
|
2056
|
+
</kendo-grid-column>
|
|
2057
|
+
</kendo-grid>
|
|
2058
|
+
</div>
|
|
2222
2059
|
|
|
2223
|
-
|
|
2060
|
+
<div class="selection-info" *ngIf="selectedType">
|
|
2061
|
+
<strong>Selected:</strong> {{ selectedType.rtCkTypeId }}
|
|
2062
|
+
</div>
|
|
2224
2063
|
</div>
|
|
2225
|
-
|
|
2064
|
+
|
|
2065
|
+
<kendo-dialog-actions>
|
|
2066
|
+
<button kendoButton (click)="onCancel()">Cancel</button>
|
|
2067
|
+
<button kendoButton themeColor="primary" [disabled]="!selectedType || (selectedType.isAbstract && !allowAbstract)" (click)="onConfirm()">OK</button>
|
|
2068
|
+
</kendo-dialog-actions>
|
|
2069
|
+
`, isInline: true, styles: [".ck-type-selector-container{display:flex;flex-direction:column;height:100%;padding:20px;min-width:700px;box-sizing:border-box}.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}.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}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: GridModule }, { kind: "component", type: i2$1.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: i2$1.SelectionDirective, selector: "[kendoGridSelectBy]" }, { kind: "component", type: i2$1.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterVariant", "filterable", "editable"] }, { kind: "directive", type: i2$1.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i3.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: i4.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: i4.TextBoxSuffixTemplateDirective, selector: "[kendoTextBoxSuffixTemplate]", inputs: ["showSeparator"] }, { kind: "ngmodule", type: DropDownsModule }, { kind: "component", type: i3$1.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: DialogModule }, { kind: "component", type: i5.DialogActionsComponent, selector: "kendo-dialog-actions", inputs: ["actions", "layout"], outputs: ["action"] }] });
|
|
2226
2070
|
}
|
|
2227
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type:
|
|
2071
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogComponent, decorators: [{
|
|
2228
2072
|
type: Component,
|
|
2229
|
-
args: [{ selector: 'mm-
|
|
2073
|
+
args: [{ selector: 'mm-ck-type-selector-dialog', standalone: true, imports: [
|
|
2230
2074
|
CommonModule,
|
|
2231
2075
|
FormsModule,
|
|
2232
2076
|
GridModule,
|
|
2077
|
+
ButtonsModule,
|
|
2233
2078
|
InputsModule,
|
|
2234
2079
|
DropDownsModule,
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2080
|
+
IconsModule,
|
|
2081
|
+
LoaderModule,
|
|
2082
|
+
DialogModule
|
|
2238
2083
|
], template: `
|
|
2239
|
-
<div class="
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
<
|
|
2267
|
-
<
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
</kendo-svgicon>
|
|
2273
|
-
}
|
|
2274
|
-
<div class="property-info">
|
|
2275
|
-
<span class="property-name" [title]="dataItem.description">
|
|
2276
|
-
{{ dataItem.displayName || dataItem.name }}
|
|
2277
|
-
</span>
|
|
2278
|
-
@if (dataItem.required) {
|
|
2279
|
-
<span class="required-indicator">*</span>
|
|
2280
|
-
}
|
|
2281
|
-
@if (dataItem.readOnly) {
|
|
2282
|
-
<span class="readonly-indicator" title="Read-only">🔒</span>
|
|
2283
|
-
}
|
|
2284
|
-
</div>
|
|
2285
|
-
</div>
|
|
2286
|
-
</ng-template>
|
|
2287
|
-
</kendo-grid-column>
|
|
2288
|
-
|
|
2289
|
-
<!-- Property Value Column -->
|
|
2290
|
-
<kendo-grid-column
|
|
2291
|
-
field="value"
|
|
2292
|
-
title="Value"
|
|
2293
|
-
[sortable]="false">
|
|
2294
|
-
<ng-template kendoGridCellTemplate let-dataItem="dataItem">
|
|
2295
|
-
<mm-property-value-display
|
|
2296
|
-
[value]="dataItem.value"
|
|
2297
|
-
[type]="dataItem.type"
|
|
2298
|
-
(binaryDownload)="onBinaryDownload($event)">
|
|
2299
|
-
</mm-property-value-display>
|
|
2300
|
-
</ng-template>
|
|
2301
|
-
</kendo-grid-column>
|
|
2084
|
+
<div class="ck-type-selector-container">
|
|
2085
|
+
<div class="filter-container">
|
|
2086
|
+
<div class="filter-row">
|
|
2087
|
+
<div class="filter-item">
|
|
2088
|
+
<label>Model Filter</label>
|
|
2089
|
+
<kendo-combobox
|
|
2090
|
+
[data]="availableModels"
|
|
2091
|
+
[(ngModel)]="selectedModel"
|
|
2092
|
+
(valueChange)="onModelFilterChange($event)"
|
|
2093
|
+
[allowCustom]="false"
|
|
2094
|
+
[clearButton]="true"
|
|
2095
|
+
placeholder="All Models"
|
|
2096
|
+
class="filter-input">
|
|
2097
|
+
</kendo-combobox>
|
|
2098
|
+
</div>
|
|
2099
|
+
<div class="filter-item flex-grow">
|
|
2100
|
+
<label>Type Search</label>
|
|
2101
|
+
<kendo-textbox
|
|
2102
|
+
[(ngModel)]="searchText"
|
|
2103
|
+
(ngModelChange)="onSearchChange($event)"
|
|
2104
|
+
placeholder="Search types..."
|
|
2105
|
+
class="filter-input">
|
|
2106
|
+
<ng-template kendoTextBoxSuffixTemplate>
|
|
2107
|
+
<button kendoButton [svgIcon]="searchIcon" fillMode="clear" size="small"></button>
|
|
2108
|
+
</ng-template>
|
|
2109
|
+
</kendo-textbox>
|
|
2110
|
+
</div>
|
|
2111
|
+
<div class="filter-item filter-actions">
|
|
2112
|
+
<label> </label>
|
|
2113
|
+
<button kendoButton [svgIcon]="filterClearIcon" (click)="clearFilters()" title="Clear filters"></button>
|
|
2114
|
+
</div>
|
|
2115
|
+
</div>
|
|
2116
|
+
</div>
|
|
2302
2117
|
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2118
|
+
<div class="grid-container">
|
|
2119
|
+
<kendo-grid
|
|
2120
|
+
[data]="gridData"
|
|
2121
|
+
[loading]="isLoading"
|
|
2122
|
+
[height]="400"
|
|
2123
|
+
[selectable]="{ mode: 'single' }"
|
|
2124
|
+
[pageable]="{ pageSizes: [25, 50, 100] }"
|
|
2125
|
+
[pageSize]="pageSize"
|
|
2126
|
+
[skip]="skip"
|
|
2127
|
+
(pageChange)="onPageChange($event)"
|
|
2128
|
+
(selectionChange)="onSelectionChange($event)"
|
|
2129
|
+
[kendoGridSelectBy]="selectItemBy"
|
|
2130
|
+
[(selectedKeys)]="selectedKeys"
|
|
2131
|
+
class="type-grid">
|
|
2132
|
+
<kendo-grid-column field="rtCkTypeId" title="Type" [width]="300">
|
|
2133
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
2134
|
+
<span [class.abstract-type]="dataItem.isAbstract" [class.final-type]="dataItem.isFinal">
|
|
2135
|
+
{{ dataItem.rtCkTypeId }}
|
|
2313
2136
|
</span>
|
|
2137
|
+
<span *ngIf="dataItem.isAbstract" class="type-badge abstract">abstract</span>
|
|
2138
|
+
<span *ngIf="dataItem.isFinal" class="type-badge final">final</span>
|
|
2314
2139
|
</ng-template>
|
|
2315
2140
|
</kendo-grid-column>
|
|
2316
|
-
|
|
2141
|
+
<kendo-grid-column field="baseTypeRtCkTypeId" title="Base Type" [width]="200">
|
|
2142
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
2143
|
+
{{ dataItem.baseTypeRtCkTypeId || '-' }}
|
|
2144
|
+
</ng-template>
|
|
2145
|
+
</kendo-grid-column>
|
|
2146
|
+
<kendo-grid-column field="description" title="Description">
|
|
2147
|
+
<ng-template kendoGridCellTemplate let-dataItem>
|
|
2148
|
+
{{ dataItem.description || '-' }}
|
|
2149
|
+
</ng-template>
|
|
2150
|
+
</kendo-grid-column>
|
|
2151
|
+
</kendo-grid>
|
|
2152
|
+
</div>
|
|
2317
2153
|
|
|
2318
|
-
|
|
2154
|
+
<div class="selection-info" *ngIf="selectedType">
|
|
2155
|
+
<strong>Selected:</strong> {{ selectedType.rtCkTypeId }}
|
|
2156
|
+
</div>
|
|
2319
2157
|
</div>
|
|
2320
|
-
`, 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"] }]
|
|
2321
|
-
}], propDecorators: { data: [{
|
|
2322
|
-
type: Input
|
|
2323
|
-
}], config: [{
|
|
2324
|
-
type: Input
|
|
2325
|
-
}], showTypeColumn: [{
|
|
2326
|
-
type: Input
|
|
2327
|
-
}], propertyChange: [{
|
|
2328
|
-
type: Output
|
|
2329
|
-
}], saveRequested: [{
|
|
2330
|
-
type: Output
|
|
2331
|
-
}], binaryDownload: [{
|
|
2332
|
-
type: Output
|
|
2333
|
-
}] } });
|
|
2334
2158
|
|
|
2335
|
-
|
|
2159
|
+
<kendo-dialog-actions>
|
|
2160
|
+
<button kendoButton (click)="onCancel()">Cancel</button>
|
|
2161
|
+
<button kendoButton themeColor="primary" [disabled]="!selectedType || (selectedType.isAbstract && !allowAbstract)" (click)="onConfirm()">OK</button>
|
|
2162
|
+
</kendo-dialog-actions>
|
|
2163
|
+
`, styles: [".ck-type-selector-container{display:flex;flex-direction:column;height:100%;padding:20px;min-width:700px;box-sizing:border-box}.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}.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}\n"] }]
|
|
2164
|
+
}], ctorParameters: () => [] });
|
|
2165
|
+
|
|
2166
|
+
class CkTypeSelectorDialogService {
|
|
2167
|
+
dialogService = inject(DialogService);
|
|
2168
|
+
/**
|
|
2169
|
+
* Opens the CkType selector dialog
|
|
2170
|
+
* @param options Dialog options
|
|
2171
|
+
* @returns Promise that resolves with the result containing selected CkType and confirmation status
|
|
2172
|
+
*/
|
|
2173
|
+
async openCkTypeSelector(options = {}) {
|
|
2174
|
+
const data = {
|
|
2175
|
+
selectedCkTypeId: options.selectedCkTypeId,
|
|
2176
|
+
ckModelIds: options.ckModelIds,
|
|
2177
|
+
dialogTitle: options.dialogTitle,
|
|
2178
|
+
allowAbstract: options.allowAbstract
|
|
2179
|
+
};
|
|
2180
|
+
const dialogRef = this.dialogService.open({
|
|
2181
|
+
content: CkTypeSelectorDialogComponent,
|
|
2182
|
+
width: 900,
|
|
2183
|
+
height: 650,
|
|
2184
|
+
minWidth: 750,
|
|
2185
|
+
minHeight: 550,
|
|
2186
|
+
title: options.dialogTitle || 'Select Construction Kit Type'
|
|
2187
|
+
});
|
|
2188
|
+
// Pass data to the component
|
|
2189
|
+
if (dialogRef.content?.instance) {
|
|
2190
|
+
dialogRef.content.instance.data = data;
|
|
2191
|
+
}
|
|
2192
|
+
try {
|
|
2193
|
+
const result = await firstValueFrom(dialogRef.result);
|
|
2194
|
+
if (result && typeof result === 'object' && 'selectedCkType' in result) {
|
|
2195
|
+
// User clicked OK and we have a result
|
|
2196
|
+
const dialogResult = result;
|
|
2197
|
+
return {
|
|
2198
|
+
confirmed: true,
|
|
2199
|
+
selectedCkType: dialogResult.selectedCkType
|
|
2200
|
+
};
|
|
2201
|
+
}
|
|
2202
|
+
else {
|
|
2203
|
+
// User clicked Cancel or closed dialog
|
|
2204
|
+
return {
|
|
2205
|
+
confirmed: false,
|
|
2206
|
+
selectedCkType: null
|
|
2207
|
+
};
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
catch {
|
|
2211
|
+
// Dialog was closed without result (e.g., ESC key, X button)
|
|
2212
|
+
return {
|
|
2213
|
+
confirmed: false,
|
|
2214
|
+
selectedCkType: null
|
|
2215
|
+
};
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2219
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogService });
|
|
2220
|
+
}
|
|
2221
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CkTypeSelectorDialogService, decorators: [{
|
|
2222
|
+
type: Injectable
|
|
2223
|
+
}] });
|
|
2224
|
+
|
|
2225
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2226
|
+
class OctoGraphQlDataSource extends DataSourceTyped {
|
|
2227
|
+
_searchFilterAttributePaths = [];
|
|
2228
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2229
|
+
constructor(listViewComponent) {
|
|
2230
|
+
super(listViewComponent);
|
|
2231
|
+
}
|
|
2232
|
+
get searchFilterAttributePaths() {
|
|
2233
|
+
return this._searchFilterAttributePaths;
|
|
2234
|
+
}
|
|
2235
|
+
set searchFilterAttributePaths(value) {
|
|
2236
|
+
this._searchFilterAttributePaths = value;
|
|
2237
|
+
}
|
|
2238
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2239
|
+
getFieldFilterDefinitions(state) {
|
|
2240
|
+
let fieldFilters = null;
|
|
2241
|
+
if (state.filter?.filters) {
|
|
2242
|
+
fieldFilters = state.filter.filters.map((f) => {
|
|
2243
|
+
if (isCompositeFilterDescriptor(f)) {
|
|
2244
|
+
throw new Error('Composite filter descriptor not supported');
|
|
2245
|
+
}
|
|
2246
|
+
const { operator, value } = OctoGraphQlDataSource.getOperatorAndValue(f.operator, f.value);
|
|
2247
|
+
return {
|
|
2248
|
+
attributePath: f.field,
|
|
2249
|
+
operator: operator,
|
|
2250
|
+
comparisonValue: value
|
|
2251
|
+
};
|
|
2252
|
+
});
|
|
2253
|
+
}
|
|
2254
|
+
return fieldFilters;
|
|
2255
|
+
}
|
|
2256
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2257
|
+
getSearchFilterDefinitions(textSearchValue) {
|
|
2258
|
+
let searchFilterDto = null;
|
|
2259
|
+
if (textSearchValue) {
|
|
2260
|
+
searchFilterDto = {
|
|
2261
|
+
type: SearchFilterTypesDto.AttributeFilterDto,
|
|
2262
|
+
attributePaths: this.searchFilterAttributePaths,
|
|
2263
|
+
searchTerm: textSearchValue,
|
|
2264
|
+
};
|
|
2265
|
+
}
|
|
2266
|
+
return searchFilterDto;
|
|
2267
|
+
}
|
|
2268
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2269
|
+
getSortDefinitions(state) {
|
|
2270
|
+
let sort = null;
|
|
2271
|
+
if (state.sort) {
|
|
2272
|
+
sort = new Array();
|
|
2273
|
+
state.sort.forEach((s) => {
|
|
2274
|
+
switch (s.dir) {
|
|
2275
|
+
case 'asc':
|
|
2276
|
+
sort?.push({
|
|
2277
|
+
attributePath: s.field,
|
|
2278
|
+
sortOrder: SortOrdersDto.AscendingDto
|
|
2279
|
+
});
|
|
2280
|
+
break;
|
|
2281
|
+
case 'desc':
|
|
2282
|
+
sort?.push({
|
|
2283
|
+
attributePath: s.field,
|
|
2284
|
+
sortOrder: SortOrdersDto.DescendingDto,
|
|
2285
|
+
});
|
|
2286
|
+
break;
|
|
2287
|
+
default:
|
|
2288
|
+
sort?.push({
|
|
2289
|
+
attributePath: s.field,
|
|
2290
|
+
sortOrder: SortOrdersDto.DefaultDto,
|
|
2291
|
+
});
|
|
2292
|
+
break;
|
|
2293
|
+
}
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2296
|
+
return sort;
|
|
2297
|
+
}
|
|
2298
|
+
static getOperatorAndValue(operator, value) {
|
|
2299
|
+
switch (operator) {
|
|
2300
|
+
case 'eq':
|
|
2301
|
+
return { operator: FieldFilterOperatorsDto.EqualsDto, value: value };
|
|
2302
|
+
case 'neq':
|
|
2303
|
+
return { operator: FieldFilterOperatorsDto.NotEqualsDto, value: value };
|
|
2304
|
+
case 'lt':
|
|
2305
|
+
return { operator: FieldFilterOperatorsDto.LessThanDto, value: value };
|
|
2306
|
+
case 'lte':
|
|
2307
|
+
return { operator: FieldFilterOperatorsDto.LessEqualThanDto, value: value };
|
|
2308
|
+
case 'gt':
|
|
2309
|
+
return { operator: FieldFilterOperatorsDto.GreaterThanDto, value: value };
|
|
2310
|
+
case 'gte':
|
|
2311
|
+
return { operator: FieldFilterOperatorsDto.GreaterEqualThanDto, value: value };
|
|
2312
|
+
case 'contains':
|
|
2313
|
+
return { operator: FieldFilterOperatorsDto.LikeDto, value: value };
|
|
2314
|
+
case 'doesnotcontain':
|
|
2315
|
+
return { operator: FieldFilterOperatorsDto.MatchRegExDto, value: `^(?!.*${value}).*$` };
|
|
2316
|
+
case 'startswith':
|
|
2317
|
+
return { operator: FieldFilterOperatorsDto.MatchRegExDto, value: value + '.*' };
|
|
2318
|
+
case 'endswith':
|
|
2319
|
+
return { operator: FieldFilterOperatorsDto.MatchRegExDto, value: '.*' + value };
|
|
2320
|
+
case 'isnull':
|
|
2321
|
+
return { operator: FieldFilterOperatorsDto.EqualsDto, value: null };
|
|
2322
|
+
case 'isnotnull':
|
|
2323
|
+
return { operator: FieldFilterOperatorsDto.NotEqualsDto, value: null };
|
|
2324
|
+
case 'isempty':
|
|
2325
|
+
return { operator: FieldFilterOperatorsDto.EqualsDto, value: "" };
|
|
2326
|
+
case 'isnotempty':
|
|
2327
|
+
return { operator: FieldFilterOperatorsDto.NotEqualsDto, value: "" };
|
|
2328
|
+
default:
|
|
2329
|
+
throw new Error('The filter operator is not supported');
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2334
|
+
class OctoGraphQlHierarchyDataSource extends HierarchyDataSourceBase {
|
|
2335
|
+
}
|
|
2336
2336
|
|
|
2337
2337
|
class AttributeSelectorDialogComponent extends DialogContentBase {
|
|
2338
2338
|
attributeService = inject(AttributeSelectorService);
|
|
@@ -4202,6 +4202,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
4202
4202
|
type: Input
|
|
4203
4203
|
}] } });
|
|
4204
4204
|
|
|
4205
|
+
/**
|
|
4206
|
+
* Animated OctoMesh logo loader component.
|
|
4207
|
+
* Displays the OctoMesh octopus SVG with a tentacle wave animation,
|
|
4208
|
+
* gentle bob, and pulsing glow effect.
|
|
4209
|
+
*
|
|
4210
|
+
* Uses `--kendo-color-primary` for theme-independent coloring.
|
|
4211
|
+
* Override the color via CSS `color` property on the host element.
|
|
4212
|
+
*
|
|
4213
|
+
* @example
|
|
4214
|
+
* ```html
|
|
4215
|
+
* <mm-octo-loader [size]="'medium'"></mm-octo-loader>
|
|
4216
|
+
* <mm-octo-loader [size]="'small'"></mm-octo-loader>
|
|
4217
|
+
* ```
|
|
4218
|
+
*/
|
|
4219
|
+
class OctoLoaderComponent {
|
|
4220
|
+
size = 'medium';
|
|
4221
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: OctoLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4222
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.5", type: OctoLoaderComponent, isStandalone: true, selector: "mm-octo-loader", inputs: { size: "size" }, ngImport: i0, template: `
|
|
4223
|
+
<div class="octo-loader" [class.octo-loader--small]="size === 'small'" [class.octo-loader--medium]="size === 'medium'">
|
|
4224
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 97" class="octo-loader__svg" overflow="visible">
|
|
4225
|
+
<!-- Body + head + outer arms -->
|
|
4226
|
+
<polygon fill="currentColor"
|
|
4227
|
+
points="58.19 72.13 53.34 72.13 53.34 52.74 63.04 52.74 63.04 43.04 63.04 38.19 63.04 28.49 67.89 0 43.64 4.24 34.01 4.24 14.61 4.24 0 4.24 0 18.79 0 28.49 0 40.61 0 52.74 9.7 52.74 9.7 72.13 4.85 72.13 4.85 67.28 0 67.28 0 72.13 0 76.98 4.85 76.98 14.55 76.98 14.55 72.13 14.55 52.74 14.55 52.13 14.55 47.89 4.85 47.89 4.85 43.04 4.85 36.37 4.85 23.64 4.85 17.58 4.85 9.09 19.4 9.09 33.94 9.09 43.64 9.09 62.01 6.02 58.19 28.49 58.19 33.34 58.19 38.19 58.19 43.04 58.19 47.89 48.49 47.89 48.49 52.13 48.49 52.74 48.49 72.13 48.49 76.98 58.19 76.98 63.04 76.98 63.04 76.98 63.04 67.28 58.19 67.28 58.19 72.13"/>
|
|
4228
|
+
<!-- Eyes -->
|
|
4229
|
+
<rect fill="currentColor" x="18.79" y="19.4" width="4.85" height="13.94"/>
|
|
4230
|
+
<rect fill="currentColor" x="38.79" y="19.4" width="4.85" height="13.94"/>
|
|
4231
|
+
<!-- Left tentacle pair -->
|
|
4232
|
+
<polygon class="octo-leg octo-leg--left" fill="currentColor"
|
|
4233
|
+
points="19.4 91.53 14.55 91.53 14.55 81.83 9.7 81.83 9.7 91.53 9.7 96.38 14.55 96.38 19.4 96.38 24.25 96.38 24.25 91.53 24.25 52.74 19.4 52.74 19.4 91.53"/>
|
|
4234
|
+
<!-- Center tentacle -->
|
|
4235
|
+
<rect class="octo-leg octo-leg--center" fill="currentColor"
|
|
4236
|
+
x="29.1" y="52.74" width="4.85" height="33.94"/>
|
|
4237
|
+
<!-- Right tentacle pair -->
|
|
4238
|
+
<polygon class="octo-leg octo-leg--right" fill="currentColor"
|
|
4239
|
+
points="48.49 91.53 43.64 91.53 43.64 52.74 38.79 52.74 38.79 91.53 38.79 96.38 43.64 96.38 48.49 96.38 53.34 96.38 53.34 91.53 53.34 81.83 48.49 81.83 48.49 91.53"/>
|
|
4240
|
+
</svg>
|
|
4241
|
+
</div>
|
|
4242
|
+
`, 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;animation:octo-spin 6s ease-in-out infinite}.octo-loader--small .octo-loader__svg{width:24px;height:24px}.octo-loader--medium .octo-loader__svg{width:48px;height:48px}.octo-loader__svg{animation:octo-glow 6s ease-in-out infinite}.octo-leg{transform-box:fill-box;transform-origin:50% 0%}.octo-leg--left{animation:octo-wiggle-left 6s ease-in-out infinite}.octo-leg--center{animation:octo-wiggle-center 6s ease-in-out infinite}.octo-leg--right{animation:octo-wiggle-right 6s ease-in-out infinite}@keyframes octo-spin{0%{transform:rotate(0) scale(1)}5%{transform:rotate(0) scale(1)}15%{transform:rotate(360deg) scale(.85)}20%{transform:rotate(360deg) scale(1)}25%{transform:rotate(360deg) scale(1)}40%{transform:rotate(0) scale(.85)}45%{transform:rotate(0) scale(1)}to{transform:rotate(0) scale(1)}}@keyframes octo-glow{0%,5%{filter:drop-shadow(0 0 2px currentColor)}15%{filter:drop-shadow(0 0 14px currentColor)}20%,25%{filter:drop-shadow(0 0 6px currentColor)}40%{filter:drop-shadow(0 0 14px currentColor)}50%,to{filter:drop-shadow(0 0 2px currentColor)}}@keyframes octo-wiggle-left{0%,47%{transform:rotate(0)}50%{transform:rotate(12deg)}53%{transform:rotate(-10deg)}56%{transform:rotate(10deg)}59%{transform:rotate(-8deg)}62%{transform:rotate(6deg)}65%{transform:rotate(-3deg)}68%{transform:rotate(0)}to{transform:rotate(0)}}@keyframes octo-wiggle-center{0%,48%{transform:rotate(0)}51%{transform:rotate(-10deg)}54%{transform:rotate(9deg)}57%{transform:rotate(-8deg)}60%{transform:rotate(7deg)}63%{transform:rotate(-4deg)}66%{transform:rotate(2deg)}69%{transform:rotate(0)}to{transform:rotate(0)}}@keyframes octo-wiggle-right{0%,49%{transform:rotate(0)}52%{transform:rotate(-12deg)}55%{transform:rotate(10deg)}58%{transform:rotate(-10deg)}61%{transform:rotate(8deg)}64%{transform:rotate(-6deg)}67%{transform:rotate(3deg)}70%{transform:rotate(0)}to{transform:rotate(0)}}\n"] });
|
|
4243
|
+
}
|
|
4244
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: OctoLoaderComponent, decorators: [{
|
|
4245
|
+
type: Component,
|
|
4246
|
+
args: [{ selector: 'mm-octo-loader', standalone: true, template: `
|
|
4247
|
+
<div class="octo-loader" [class.octo-loader--small]="size === 'small'" [class.octo-loader--medium]="size === 'medium'">
|
|
4248
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 97" class="octo-loader__svg" overflow="visible">
|
|
4249
|
+
<!-- Body + head + outer arms -->
|
|
4250
|
+
<polygon fill="currentColor"
|
|
4251
|
+
points="58.19 72.13 53.34 72.13 53.34 52.74 63.04 52.74 63.04 43.04 63.04 38.19 63.04 28.49 67.89 0 43.64 4.24 34.01 4.24 14.61 4.24 0 4.24 0 18.79 0 28.49 0 40.61 0 52.74 9.7 52.74 9.7 72.13 4.85 72.13 4.85 67.28 0 67.28 0 72.13 0 76.98 4.85 76.98 14.55 76.98 14.55 72.13 14.55 52.74 14.55 52.13 14.55 47.89 4.85 47.89 4.85 43.04 4.85 36.37 4.85 23.64 4.85 17.58 4.85 9.09 19.4 9.09 33.94 9.09 43.64 9.09 62.01 6.02 58.19 28.49 58.19 33.34 58.19 38.19 58.19 43.04 58.19 47.89 48.49 47.89 48.49 52.13 48.49 52.74 48.49 72.13 48.49 76.98 58.19 76.98 63.04 76.98 63.04 76.98 63.04 67.28 58.19 67.28 58.19 72.13"/>
|
|
4252
|
+
<!-- Eyes -->
|
|
4253
|
+
<rect fill="currentColor" x="18.79" y="19.4" width="4.85" height="13.94"/>
|
|
4254
|
+
<rect fill="currentColor" x="38.79" y="19.4" width="4.85" height="13.94"/>
|
|
4255
|
+
<!-- Left tentacle pair -->
|
|
4256
|
+
<polygon class="octo-leg octo-leg--left" fill="currentColor"
|
|
4257
|
+
points="19.4 91.53 14.55 91.53 14.55 81.83 9.7 81.83 9.7 91.53 9.7 96.38 14.55 96.38 19.4 96.38 24.25 96.38 24.25 91.53 24.25 52.74 19.4 52.74 19.4 91.53"/>
|
|
4258
|
+
<!-- Center tentacle -->
|
|
4259
|
+
<rect class="octo-leg octo-leg--center" fill="currentColor"
|
|
4260
|
+
x="29.1" y="52.74" width="4.85" height="33.94"/>
|
|
4261
|
+
<!-- Right tentacle pair -->
|
|
4262
|
+
<polygon class="octo-leg octo-leg--right" fill="currentColor"
|
|
4263
|
+
points="48.49 91.53 43.64 91.53 43.64 52.74 38.79 52.74 38.79 91.53 38.79 96.38 43.64 96.38 48.49 96.38 53.34 96.38 53.34 91.53 53.34 81.83 48.49 81.83 48.49 91.53"/>
|
|
4264
|
+
</svg>
|
|
4265
|
+
</div>
|
|
4266
|
+
`, 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;animation:octo-spin 6s ease-in-out infinite}.octo-loader--small .octo-loader__svg{width:24px;height:24px}.octo-loader--medium .octo-loader__svg{width:48px;height:48px}.octo-loader__svg{animation:octo-glow 6s ease-in-out infinite}.octo-leg{transform-box:fill-box;transform-origin:50% 0%}.octo-leg--left{animation:octo-wiggle-left 6s ease-in-out infinite}.octo-leg--center{animation:octo-wiggle-center 6s ease-in-out infinite}.octo-leg--right{animation:octo-wiggle-right 6s ease-in-out infinite}@keyframes octo-spin{0%{transform:rotate(0) scale(1)}5%{transform:rotate(0) scale(1)}15%{transform:rotate(360deg) scale(.85)}20%{transform:rotate(360deg) scale(1)}25%{transform:rotate(360deg) scale(1)}40%{transform:rotate(0) scale(.85)}45%{transform:rotate(0) scale(1)}to{transform:rotate(0) scale(1)}}@keyframes octo-glow{0%,5%{filter:drop-shadow(0 0 2px currentColor)}15%{filter:drop-shadow(0 0 14px currentColor)}20%,25%{filter:drop-shadow(0 0 6px currentColor)}40%{filter:drop-shadow(0 0 14px currentColor)}50%,to{filter:drop-shadow(0 0 2px currentColor)}}@keyframes octo-wiggle-left{0%,47%{transform:rotate(0)}50%{transform:rotate(12deg)}53%{transform:rotate(-10deg)}56%{transform:rotate(10deg)}59%{transform:rotate(-8deg)}62%{transform:rotate(6deg)}65%{transform:rotate(-3deg)}68%{transform:rotate(0)}to{transform:rotate(0)}}@keyframes octo-wiggle-center{0%,48%{transform:rotate(0)}51%{transform:rotate(-10deg)}54%{transform:rotate(9deg)}57%{transform:rotate(-8deg)}60%{transform:rotate(7deg)}63%{transform:rotate(-4deg)}66%{transform:rotate(2deg)}69%{transform:rotate(0)}to{transform:rotate(0)}}@keyframes octo-wiggle-right{0%,49%{transform:rotate(0)}52%{transform:rotate(-12deg)}55%{transform:rotate(10deg)}58%{transform:rotate(-10deg)}61%{transform:rotate(8deg)}64%{transform:rotate(-6deg)}67%{transform:rotate(3deg)}70%{transform:rotate(0)}to{transform:rotate(0)}}\n"] }]
|
|
4267
|
+
}], propDecorators: { size: [{
|
|
4268
|
+
type: Input
|
|
4269
|
+
}] } });
|
|
4270
|
+
|
|
4205
4271
|
/*
|
|
4206
4272
|
* Public API Surface of octo-ui
|
|
4207
4273
|
*/
|
|
@@ -4224,5 +4290,5 @@ function provideOctoUi() {
|
|
|
4224
4290
|
* Generated bundle index. Do not edit.
|
|
4225
4291
|
*/
|
|
4226
4292
|
|
|
4227
|
-
export { AttributeSelectorDialogComponent, AttributeSelectorDialogService, AttributeSortSelectorDialogComponent, AttributeSortSelectorDialogService, AttributeValueTypeDto, CkTypeSelectorDialogComponent, CkTypeSelectorDialogService, CkTypeSelectorInputComponent, DefaultPropertyCategory, EntityIdInfoComponent, FieldFilterEditorComponent, OctoGraphQlDataSource, OctoGraphQlHierarchyDataSource, PropertyConverterService, PropertyDisplayMode, PropertyGridComponent, PropertyValueDisplayComponent, provideOctoUi };
|
|
4293
|
+
export { AttributeSelectorDialogComponent, AttributeSelectorDialogService, AttributeSortSelectorDialogComponent, AttributeSortSelectorDialogService, AttributeValueTypeDto, CkTypeSelectorDialogComponent, CkTypeSelectorDialogService, CkTypeSelectorInputComponent, DefaultPropertyCategory, EntityIdInfoComponent, FieldFilterEditorComponent, OctoGraphQlDataSource, OctoGraphQlHierarchyDataSource, OctoLoaderComponent, PropertyConverterService, PropertyDisplayMode, PropertyGridComponent, PropertyValueDisplayComponent, provideOctoUi };
|
|
4228
4294
|
//# sourceMappingURL=meshmakers-octo-ui.mjs.map
|