@meshmakers/octo-ui 3.3.580 → 3.3.600
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/meshmakers-octo-ui.mjs +288 -55
- package/fesm2022/meshmakers-octo-ui.mjs.map +1 -1
- package/lib/runtime-browser/styles/_index.scss +4954 -0
- package/lib/runtime-browser/styles/_kendo-theme.scss +224 -0
- package/lib/runtime-browser/styles/_variables.scss +196 -0
- package/package.json +2 -1
- package/styles/_index.scss +3 -0
- package/styles/_with-kendo.scss +8 -0
- package/types/meshmakers-octo-ui.d.ts +60 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Component, Injectable, EventEmitter, Output, Input, ElementRef, forwardRef, ViewChild, signal, computed, makeEnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { inject, Component, Injectable, EventEmitter, Output, Input, ElementRef, forwardRef, ViewChild, signal, computed, HostListener, makeEnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { AttributeSelectorService, AttributeValueTypeDto as AttributeValueTypeDto$1, CkTypeAttributeService, CkTypeSelectorService, GetEntitiesByCkTypeDtoGQL, RuntimeEntitySelectDataSource, RuntimeEntityDialogDataSource, SearchFilterTypesDto, SortOrdersDto, FieldFilterOperatorsDto, provideOctoServices } from '@meshmakers/octo-services';
|
|
4
4
|
import { WindowStateService, EntitySelectInputComponent, DataSourceTyped, HierarchyDataSourceBase, NotificationDisplayService, provideMmSharedUi } from '@meshmakers/shared-ui';
|
|
5
5
|
import { provideMmSharedAuth } from '@meshmakers/shared-auth';
|
|
@@ -10,14 +10,14 @@ import { FormsModule, FormControl, ReactiveFormsModule, NG_VALUE_ACCESSOR, NG_VA
|
|
|
10
10
|
import * as i3 from '@progress/kendo-angular-grid';
|
|
11
11
|
import { GridModule } from '@progress/kendo-angular-grid';
|
|
12
12
|
import * as i4 from '@progress/kendo-angular-buttons';
|
|
13
|
-
import { ButtonsModule, ButtonModule } from '@progress/kendo-angular-buttons';
|
|
13
|
+
import { ButtonsModule, ButtonModule, ButtonComponent } from '@progress/kendo-angular-buttons';
|
|
14
14
|
import * as i5 from '@progress/kendo-angular-inputs';
|
|
15
15
|
import { InputsModule } from '@progress/kendo-angular-inputs';
|
|
16
16
|
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
|
-
import { IconsModule, SVGIconModule } from '@progress/kendo-angular-icons';
|
|
20
|
-
import { searchIcon, sortAscSmallIcon, sortDescSmallIcon, chevronRightIcon, chevronDownIcon, downloadIcon, fileIcon, folderIcon, calendarIcon, checkboxCheckedIcon, listUnorderedIcon, filterClearIcon, arrowRightIcon, arrowLeftIcon, chevronDoubleRightIcon, chevronDoubleLeftIcon, arrowUpIcon, arrowDownIcon, pencilIcon, trashIcon, plusIcon, minusIcon, dollarIcon, copyIcon } from '@progress/kendo-svg-icons';
|
|
19
|
+
import { IconsModule, SVGIconModule, SVGIconComponent } from '@progress/kendo-angular-icons';
|
|
20
|
+
import { searchIcon, sortAscSmallIcon, sortDescSmallIcon, chevronRightIcon, chevronDownIcon, downloadIcon, fileIcon, folderIcon, calendarIcon, checkboxCheckedIcon, listUnorderedIcon, filterClearIcon, arrowRightIcon, arrowLeftIcon, chevronDoubleRightIcon, chevronDoubleLeftIcon, arrowUpIcon, arrowDownIcon, pencilIcon, trashIcon, plusIcon, minusIcon, dollarIcon, copyIcon, arrowRotateCwIcon } from '@progress/kendo-svg-icons';
|
|
21
21
|
import { WindowRef, WindowModule, WindowService, WindowCloseResult } from '@progress/kendo-angular-dialog';
|
|
22
22
|
import { Subject, firstValueFrom, of, forkJoin, Subscription } from 'rxjs';
|
|
23
23
|
import { debounceTime, distinctUntilChanged, switchMap, map, tap, catchError } from 'rxjs/operators';
|
|
@@ -25,7 +25,7 @@ import { LoaderModule } from '@progress/kendo-angular-indicators';
|
|
|
25
25
|
import { isCompositeFilterDescriptor } from '@progress/kendo-data-query';
|
|
26
26
|
import * as i6 from '@progress/kendo-angular-dateinputs';
|
|
27
27
|
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
|
|
28
|
-
import { PopupModule } from '@progress/kendo-angular-popup';
|
|
28
|
+
import { PopupModule, PopupComponent } from '@progress/kendo-angular-popup';
|
|
29
29
|
import { IntlModule } from '@progress/kendo-angular-intl';
|
|
30
30
|
|
|
31
31
|
class AttributeSortSelectorDialogComponent {
|
|
@@ -35,6 +35,8 @@ class AttributeSortSelectorDialogComponent {
|
|
|
35
35
|
// Dialog data
|
|
36
36
|
data;
|
|
37
37
|
ckTypeId;
|
|
38
|
+
includeNavigationProperties = undefined;
|
|
39
|
+
attributePathsSet = null;
|
|
38
40
|
searchText = '';
|
|
39
41
|
currentSortOrder = 'standard';
|
|
40
42
|
selectedValueTypeFilter = null;
|
|
@@ -77,6 +79,8 @@ class AttributeSortSelectorDialogComponent {
|
|
|
77
79
|
if (this.data) {
|
|
78
80
|
this.ckTypeId = this.data.ckTypeId;
|
|
79
81
|
this.dialogTitle = this.data.dialogTitle || 'Select Attributes with Sort Order';
|
|
82
|
+
this.includeNavigationProperties = this.data.includeNavigationProperties;
|
|
83
|
+
this.attributePathsSet = this.data.attributePaths ? new Set(this.data.attributePaths) : null;
|
|
80
84
|
if (this.data.selectedAttributes && this.data.selectedAttributes.length > 0) {
|
|
81
85
|
this.selectedAttributes = [...this.data.selectedAttributes];
|
|
82
86
|
this.updateSelectedGrid();
|
|
@@ -90,10 +94,14 @@ class AttributeSortSelectorDialogComponent {
|
|
|
90
94
|
this.loadAvailableAttributes();
|
|
91
95
|
}
|
|
92
96
|
loadAvailableAttributes(searchTerm) {
|
|
93
|
-
this.attributeService.getAvailableAttributes(this.ckTypeId, undefined, undefined, undefined, this.selectedValueTypeFilter || undefined, searchTerm || undefined).subscribe(result => {
|
|
97
|
+
this.attributeService.getAvailableAttributes(this.ckTypeId, undefined, undefined, undefined, this.selectedValueTypeFilter || undefined, searchTerm || undefined, this.includeNavigationProperties, undefined).subscribe(result => {
|
|
94
98
|
// Filter out already selected attributes
|
|
95
99
|
const selectedPaths = new Set(this.selectedAttributes.map(a => a.attributePath));
|
|
96
|
-
|
|
100
|
+
// Apply client-side attribute path restriction if set
|
|
101
|
+
const filteredItems = this.attributePathsSet
|
|
102
|
+
? result.items.filter(item => this.attributePathsSet.has(item.attributePath))
|
|
103
|
+
: result.items;
|
|
104
|
+
this.availableAttributes = filteredItems.filter(item => !selectedPaths.has(item.attributePath));
|
|
97
105
|
this.updateAvailableGrid();
|
|
98
106
|
});
|
|
99
107
|
}
|
|
@@ -499,13 +507,18 @@ class AttributeSortSelectorDialogService {
|
|
|
499
507
|
* @param ckTypeId The CkType ID to fetch attributes for
|
|
500
508
|
* @param selectedAttributes Optional array of pre-selected attributes with sort orders
|
|
501
509
|
* @param dialogTitle Optional custom dialog title
|
|
510
|
+
* @param includeNavigationProperties Optional flag to control navigation property inclusion
|
|
511
|
+
* @param hideNavigationControls Optional flag to hide the navigation property controls
|
|
502
512
|
* @returns Promise that resolves with the result containing selected attributes with sort orders and confirmation status
|
|
503
513
|
*/
|
|
504
|
-
async openAttributeSortSelector(ckTypeId, selectedAttributes, dialogTitle) {
|
|
514
|
+
async openAttributeSortSelector(ckTypeId, selectedAttributes, dialogTitle, includeNavigationProperties, hideNavigationControls, attributePaths) {
|
|
505
515
|
const data = {
|
|
506
516
|
ckTypeId,
|
|
507
517
|
selectedAttributes,
|
|
508
|
-
dialogTitle
|
|
518
|
+
dialogTitle,
|
|
519
|
+
includeNavigationProperties,
|
|
520
|
+
hideNavigationControls,
|
|
521
|
+
attributePaths
|
|
509
522
|
};
|
|
510
523
|
const size = this.windowStateService.resolveWindowSize('attribute-sort-selector', { width: 1200, height: 750 });
|
|
511
524
|
const windowRef = this.windowService.open({
|
|
@@ -2701,11 +2714,14 @@ class AttributeSelectorDialogComponent {
|
|
|
2701
2714
|
dialogTitle = 'Select Attributes';
|
|
2702
2715
|
rtCkTypeId;
|
|
2703
2716
|
singleSelect = false;
|
|
2717
|
+
additionalAttributes = [];
|
|
2704
2718
|
searchText = '';
|
|
2705
2719
|
selectedSingleKey = [];
|
|
2706
2720
|
selectedValueTypeFilter = null;
|
|
2707
2721
|
includeNavigationProperties = true;
|
|
2708
2722
|
maxDepth = null;
|
|
2723
|
+
hideNavigationControls = false;
|
|
2724
|
+
attributePathsSet = null;
|
|
2709
2725
|
availableAttributes = [];
|
|
2710
2726
|
selectedAttributes = [];
|
|
2711
2727
|
availableGridData = { data: [], total: 0 };
|
|
@@ -2734,6 +2750,9 @@ class AttributeSelectorDialogComponent {
|
|
|
2734
2750
|
this.singleSelect = this.data.singleSelect ?? false;
|
|
2735
2751
|
this.includeNavigationProperties = this.data.includeNavigationProperties ?? true;
|
|
2736
2752
|
this.maxDepth = this.data.maxDepth ?? null;
|
|
2753
|
+
this.additionalAttributes = this.data.additionalAttributes ?? [];
|
|
2754
|
+
this.hideNavigationControls = this.data.hideNavigationControls ?? false;
|
|
2755
|
+
this.attributePathsSet = this.data.attributePaths ? new Set(this.data.attributePaths) : null;
|
|
2737
2756
|
if (this.data.selectedAttributes && this.data.selectedAttributes.length > 0) {
|
|
2738
2757
|
if (this.singleSelect) {
|
|
2739
2758
|
this.selectedSingleKey = [this.data.selectedAttributes[0]];
|
|
@@ -2755,15 +2774,35 @@ class AttributeSelectorDialogComponent {
|
|
|
2755
2774
|
this.attributeService.getAvailableAttributes(this.rtCkTypeId, undefined, undefined, undefined, this.selectedValueTypeFilter || undefined, searchTerm || undefined, this.includeNavigationProperties, this.maxDepth ?? undefined).subscribe(result => {
|
|
2756
2775
|
// Filter out already selected attributes
|
|
2757
2776
|
const selectedPaths = new Set(this.selectedAttributes.map(a => a.attributePath));
|
|
2758
|
-
|
|
2777
|
+
// Apply client-side attribute path restriction if set (additionalAttributes bypass this filter intentionally)
|
|
2778
|
+
const filteredItems = this.attributePathsSet
|
|
2779
|
+
? result.items.filter(item => this.attributePathsSet.has(item.attributePath))
|
|
2780
|
+
: result.items;
|
|
2781
|
+
// Include additional virtual attributes (e.g., Timestamp for stream data), filtered by search/type
|
|
2782
|
+
const filteredAdditional = this.additionalAttributes.filter(attr => {
|
|
2783
|
+
if (selectedPaths.has(attr.attributePath))
|
|
2784
|
+
return false;
|
|
2785
|
+
if (searchTerm && !attr.attributePath.toLowerCase().includes(searchTerm.toLowerCase()))
|
|
2786
|
+
return false;
|
|
2787
|
+
if (this.selectedValueTypeFilter && attr.attributeValueType !== this.selectedValueTypeFilter)
|
|
2788
|
+
return false;
|
|
2789
|
+
return true;
|
|
2790
|
+
});
|
|
2791
|
+
this.availableAttributes = [
|
|
2792
|
+
...filteredAdditional,
|
|
2793
|
+
...filteredItems.filter(item => !selectedPaths.has(item.attributePath))
|
|
2794
|
+
];
|
|
2759
2795
|
this.updateAvailableGrid();
|
|
2760
2796
|
});
|
|
2761
2797
|
}
|
|
2762
2798
|
loadInitialSelectedAttributes(attributePaths) {
|
|
2763
2799
|
// Load all attributes to get the details for selected ones
|
|
2764
2800
|
this.attributeService.getAvailableAttributes(this.rtCkTypeId).subscribe(result => {
|
|
2765
|
-
// Create a map for quick lookup
|
|
2801
|
+
// Create a map for quick lookup, including additional virtual attributes
|
|
2766
2802
|
const attributeMap = new Map(result.items.map(item => [item.attributePath, item]));
|
|
2803
|
+
for (const attr of this.additionalAttributes) {
|
|
2804
|
+
attributeMap.set(attr.attributePath, attr);
|
|
2805
|
+
}
|
|
2767
2806
|
// Preserve the order from attributePaths
|
|
2768
2807
|
this.selectedAttributes = attributePaths
|
|
2769
2808
|
.map(path => attributeMap.get(path))
|
|
@@ -2771,7 +2810,10 @@ class AttributeSelectorDialogComponent {
|
|
|
2771
2810
|
this.updateSelectedGrid();
|
|
2772
2811
|
// Filter out selected from available
|
|
2773
2812
|
const selectedPaths = new Set(this.selectedAttributes.map(a => a.attributePath));
|
|
2774
|
-
this.availableAttributes =
|
|
2813
|
+
this.availableAttributes = [
|
|
2814
|
+
...this.additionalAttributes.filter(attr => !selectedPaths.has(attr.attributePath)),
|
|
2815
|
+
...result.items.filter(item => !selectedPaths.has(item.attributePath))
|
|
2816
|
+
];
|
|
2775
2817
|
this.updateAvailableGrid();
|
|
2776
2818
|
});
|
|
2777
2819
|
}
|
|
@@ -2979,7 +3021,7 @@ class AttributeSelectorDialogComponent {
|
|
|
2979
3021
|
this.updateGrids();
|
|
2980
3022
|
}
|
|
2981
3023
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AttributeSelectorDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2982
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3024
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AttributeSelectorDialogComponent, isStandalone: true, selector: "mm-attribute-selector-dialog", ngImport: i0, template: `
|
|
2983
3025
|
<div class="attribute-selector-container">
|
|
2984
3026
|
<div class="filter-container">
|
|
2985
3027
|
<kendo-textbox
|
|
@@ -3002,23 +3044,25 @@ class AttributeSelectorDialogComponent {
|
|
|
3002
3044
|
</kendo-dropdownlist>
|
|
3003
3045
|
</div>
|
|
3004
3046
|
|
|
3005
|
-
|
|
3006
|
-
<
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3047
|
+
@if (!hideNavigationControls) {
|
|
3048
|
+
<div class="options-container">
|
|
3049
|
+
<input type="checkbox" kendoCheckBox
|
|
3050
|
+
[(ngModel)]="includeNavigationProperties"
|
|
3051
|
+
(ngModelChange)="onNavigationPropertiesChange()" />
|
|
3052
|
+
<label class="option-label">Include Navigation Properties</label>
|
|
3010
3053
|
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3054
|
+
<kendo-numerictextbox
|
|
3055
|
+
[(ngModel)]="maxDepth"
|
|
3056
|
+
[min]="1" [max]="5" [step]="1" [format]="'n0'"
|
|
3057
|
+
[placeholder]="'Depth'"
|
|
3058
|
+
[spinners]="true"
|
|
3059
|
+
[disabled]="!includeNavigationProperties"
|
|
3060
|
+
(valueChange)="onMaxDepthChange($event)"
|
|
3061
|
+
class="depth-input">
|
|
3062
|
+
</kendo-numerictextbox>
|
|
3063
|
+
<label class="option-label">Max Depth</label>
|
|
3064
|
+
</div>
|
|
3065
|
+
}
|
|
3022
3066
|
|
|
3023
3067
|
<div class="lists-container" *ngIf="!singleSelect">
|
|
3024
3068
|
<div class="list-section">
|
|
@@ -3166,23 +3210,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
3166
3210
|
</kendo-dropdownlist>
|
|
3167
3211
|
</div>
|
|
3168
3212
|
|
|
3169
|
-
|
|
3170
|
-
<
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3213
|
+
@if (!hideNavigationControls) {
|
|
3214
|
+
<div class="options-container">
|
|
3215
|
+
<input type="checkbox" kendoCheckBox
|
|
3216
|
+
[(ngModel)]="includeNavigationProperties"
|
|
3217
|
+
(ngModelChange)="onNavigationPropertiesChange()" />
|
|
3218
|
+
<label class="option-label">Include Navigation Properties</label>
|
|
3174
3219
|
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3220
|
+
<kendo-numerictextbox
|
|
3221
|
+
[(ngModel)]="maxDepth"
|
|
3222
|
+
[min]="1" [max]="5" [step]="1" [format]="'n0'"
|
|
3223
|
+
[placeholder]="'Depth'"
|
|
3224
|
+
[spinners]="true"
|
|
3225
|
+
[disabled]="!includeNavigationProperties"
|
|
3226
|
+
(valueChange)="onMaxDepthChange($event)"
|
|
3227
|
+
class="depth-input">
|
|
3228
|
+
</kendo-numerictextbox>
|
|
3229
|
+
<label class="option-label">Max Depth</label>
|
|
3230
|
+
</div>
|
|
3231
|
+
}
|
|
3186
3232
|
|
|
3187
3233
|
<div class="lists-container" *ngIf="!singleSelect">
|
|
3188
3234
|
<div class="list-section">
|
|
@@ -3306,14 +3352,23 @@ class AttributeSelectorDialogService {
|
|
|
3306
3352
|
* @param selectedAttributes Optional array of pre-selected attribute paths
|
|
3307
3353
|
* @param dialogTitle Optional custom dialog title
|
|
3308
3354
|
* @param singleSelect Optional flag for single-select mode
|
|
3355
|
+
* @param additionalAttributes Optional virtual attributes to include (e.g., Timestamp for stream data)
|
|
3356
|
+
* @param includeNavigationProperties Optional flag to control navigation property inclusion
|
|
3357
|
+
* @param maxDepth Optional max depth for navigation properties
|
|
3358
|
+
* @param hideNavigationControls Optional flag to hide the navigation property controls in the dialog
|
|
3309
3359
|
* @returns Promise that resolves with the result containing selected attributes and confirmation status
|
|
3310
3360
|
*/
|
|
3311
|
-
async openAttributeSelector(rtCkTypeId, selectedAttributes, dialogTitle, singleSelect) {
|
|
3361
|
+
async openAttributeSelector(rtCkTypeId, selectedAttributes, dialogTitle, singleSelect, additionalAttributes, includeNavigationProperties, maxDepth, hideNavigationControls, attributePaths) {
|
|
3312
3362
|
const data = {
|
|
3313
3363
|
rtCkTypeId,
|
|
3314
3364
|
selectedAttributes,
|
|
3315
3365
|
dialogTitle,
|
|
3316
|
-
singleSelect
|
|
3366
|
+
singleSelect,
|
|
3367
|
+
additionalAttributes,
|
|
3368
|
+
includeNavigationProperties,
|
|
3369
|
+
maxDepth,
|
|
3370
|
+
hideNavigationControls,
|
|
3371
|
+
attributePaths
|
|
3317
3372
|
};
|
|
3318
3373
|
const dialogKey = singleSelect ? 'attribute-selector-single' : 'attribute-selector';
|
|
3319
3374
|
const defaultWidth = singleSelect ? 550 : 1000;
|
|
@@ -3883,6 +3938,17 @@ class FieldFilterEditorComponent {
|
|
|
3883
3938
|
* When not set, the component uses the externally provided availableAttributes input.
|
|
3884
3939
|
*/
|
|
3885
3940
|
ckTypeId;
|
|
3941
|
+
/**
|
|
3942
|
+
* When true, hides the "Include Navigation Properties" checkbox and Max Depth controls,
|
|
3943
|
+
* and forces attribute loading without navigation properties.
|
|
3944
|
+
* Used for stream data queries which don't support navigation properties.
|
|
3945
|
+
*/
|
|
3946
|
+
hideNavigationProperties = false;
|
|
3947
|
+
/**
|
|
3948
|
+
* When set, restricts the available attributes to only these attribute paths (filtered client-side after fetching).
|
|
3949
|
+
* Used for stream data queries to show only stream-data-enabled attributes.
|
|
3950
|
+
*/
|
|
3951
|
+
attributePaths;
|
|
3886
3952
|
/** Enable variable mode - allows using variables instead of literal values */
|
|
3887
3953
|
enableVariables = false;
|
|
3888
3954
|
/** Available variables for selection when enableVariables is true */
|
|
@@ -3905,8 +3971,13 @@ class FieldFilterEditorComponent {
|
|
|
3905
3971
|
filtersChange = new EventEmitter();
|
|
3906
3972
|
selectedKeys = [];
|
|
3907
3973
|
ngOnChanges(changes) {
|
|
3908
|
-
//
|
|
3909
|
-
if (changes?.['
|
|
3974
|
+
// When hideNavigationProperties changes to true, reset nav props
|
|
3975
|
+
if (changes?.['hideNavigationProperties'] && this.hideNavigationProperties) {
|
|
3976
|
+
this.includeNavigationProperties = false;
|
|
3977
|
+
this.maxDepth = null;
|
|
3978
|
+
}
|
|
3979
|
+
// Reload attributes when ckTypeId, hideNavigationProperties, or attributePaths changes
|
|
3980
|
+
if ((changes?.['ckTypeId'] || changes?.['hideNavigationProperties'] || changes?.['attributePaths']) && this.ckTypeId) {
|
|
3910
3981
|
this.loadAttributesFromCkType();
|
|
3911
3982
|
}
|
|
3912
3983
|
this.filteredAttributeList = [...this.availableAttributes];
|
|
@@ -3950,14 +4021,19 @@ class FieldFilterEditorComponent {
|
|
|
3950
4021
|
if (!this.ckTypeId || !this.attributeService)
|
|
3951
4022
|
return;
|
|
3952
4023
|
this.isLoadingAttributes = true;
|
|
4024
|
+
const includeNavProps = this.hideNavigationProperties ? false : this.includeNavigationProperties;
|
|
3953
4025
|
try {
|
|
3954
4026
|
const result = await firstValueFrom(this.attributeService.getAvailableAttributes(this.ckTypeId, undefined, // filter
|
|
3955
4027
|
1000, // first
|
|
3956
4028
|
undefined, // after
|
|
3957
4029
|
undefined, // attributeValueType
|
|
3958
4030
|
undefined, // searchTerm
|
|
3959
|
-
|
|
3960
|
-
|
|
4031
|
+
includeNavProps, this.maxDepth ?? undefined));
|
|
4032
|
+
// Apply client-side attribute path restriction if set
|
|
4033
|
+
const allowedPathsSet = this.attributePaths ? new Set(this.attributePaths) : null;
|
|
4034
|
+
this.availableAttributes = allowedPathsSet
|
|
4035
|
+
? result.items.filter(item => allowedPathsSet.has(item.attributePath))
|
|
4036
|
+
: result.items;
|
|
3961
4037
|
this.filteredAttributeList = [...this.availableAttributes];
|
|
3962
4038
|
this.buildAttributeTypeMap();
|
|
3963
4039
|
}
|
|
@@ -4294,9 +4370,9 @@ class FieldFilterEditorComponent {
|
|
|
4294
4370
|
return values;
|
|
4295
4371
|
}
|
|
4296
4372
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldFilterEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4297
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: FieldFilterEditorComponent, isStandalone: true, selector: "mm-field-filter-editor", inputs: { availableAttributes: "availableAttributes", ckTypeId: "ckTypeId", enableVariables: "enableVariables", availableVariables: "availableVariables", filters: "filters" }, outputs: { filtersChange: "filtersChange" }, usesOnChanges: true, ngImport: i0, template: `
|
|
4373
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: FieldFilterEditorComponent, isStandalone: true, selector: "mm-field-filter-editor", inputs: { availableAttributes: "availableAttributes", ckTypeId: "ckTypeId", hideNavigationProperties: "hideNavigationProperties", attributePaths: "attributePaths", enableVariables: "enableVariables", availableVariables: "availableVariables", filters: "filters" }, outputs: { filtersChange: "filtersChange" }, usesOnChanges: true, ngImport: i0, template: `
|
|
4298
4374
|
<div class="field-filter-editor">
|
|
4299
|
-
@if (ckTypeId) {
|
|
4375
|
+
@if (ckTypeId && !hideNavigationProperties) {
|
|
4300
4376
|
<div class="attribute-options">
|
|
4301
4377
|
<label class="inline-checkbox">
|
|
4302
4378
|
<input type="checkbox" kendoCheckBox
|
|
@@ -4565,7 +4641,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
4565
4641
|
IntlModule
|
|
4566
4642
|
], template: `
|
|
4567
4643
|
<div class="field-filter-editor">
|
|
4568
|
-
@if (ckTypeId) {
|
|
4644
|
+
@if (ckTypeId && !hideNavigationProperties) {
|
|
4569
4645
|
<div class="attribute-options">
|
|
4570
4646
|
<label class="inline-checkbox">
|
|
4571
4647
|
<input type="checkbox" kendoCheckBox
|
|
@@ -4822,6 +4898,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
4822
4898
|
type: Input
|
|
4823
4899
|
}], ckTypeId: [{
|
|
4824
4900
|
type: Input
|
|
4901
|
+
}], hideNavigationProperties: [{
|
|
4902
|
+
type: Input
|
|
4903
|
+
}], attributePaths: [{
|
|
4904
|
+
type: Input
|
|
4825
4905
|
}], enableVariables: [{
|
|
4826
4906
|
type: Input
|
|
4827
4907
|
}], availableVariables: [{
|
|
@@ -5155,6 +5235,159 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
|
|
|
5155
5235
|
type: Input
|
|
5156
5236
|
}] } });
|
|
5157
5237
|
|
|
5238
|
+
class TenantSwitcherComponent {
|
|
5239
|
+
currentTenantId = null;
|
|
5240
|
+
allowedTenants = [];
|
|
5241
|
+
isDenied = false;
|
|
5242
|
+
tenantSelected = new EventEmitter();
|
|
5243
|
+
refreshRequested = new EventEmitter();
|
|
5244
|
+
refreshIcon = arrowRotateCwIcon;
|
|
5245
|
+
isRefreshing = false;
|
|
5246
|
+
anchor = null;
|
|
5247
|
+
popup = null;
|
|
5248
|
+
showPopup = false;
|
|
5249
|
+
onKeydown(event) {
|
|
5250
|
+
if (event.code === 'Escape') {
|
|
5251
|
+
this.showPopup = false;
|
|
5252
|
+
}
|
|
5253
|
+
}
|
|
5254
|
+
onDocumentClick(event) {
|
|
5255
|
+
if (!this.contains(event.target)) {
|
|
5256
|
+
this.showPopup = false;
|
|
5257
|
+
}
|
|
5258
|
+
}
|
|
5259
|
+
onToggle() {
|
|
5260
|
+
if (!this.isDenied) {
|
|
5261
|
+
this.showPopup = !this.showPopup;
|
|
5262
|
+
}
|
|
5263
|
+
}
|
|
5264
|
+
onSelectTenant(tenantId) {
|
|
5265
|
+
if (tenantId !== this.currentTenantId) {
|
|
5266
|
+
this.tenantSelected.emit(tenantId);
|
|
5267
|
+
}
|
|
5268
|
+
this.showPopup = false;
|
|
5269
|
+
}
|
|
5270
|
+
onRefresh(event) {
|
|
5271
|
+
event.stopPropagation();
|
|
5272
|
+
if (!this.isRefreshing) {
|
|
5273
|
+
this.isRefreshing = true;
|
|
5274
|
+
this.refreshRequested.emit();
|
|
5275
|
+
// Reset spinning after a short delay to give visual feedback
|
|
5276
|
+
setTimeout(() => this.isRefreshing = false, 1500);
|
|
5277
|
+
}
|
|
5278
|
+
}
|
|
5279
|
+
contains(target) {
|
|
5280
|
+
return ((this.anchor?.nativeElement.contains(target) ?? false) ||
|
|
5281
|
+
(this.popup?.nativeElement.contains(target) ?? false));
|
|
5282
|
+
}
|
|
5283
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: TenantSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5284
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: TenantSwitcherComponent, isStandalone: true, selector: "mm-tenant-switcher", inputs: { currentTenantId: "currentTenantId", allowedTenants: "allowedTenants", isDenied: "isDenied" }, outputs: { tenantSelected: "tenantSelected", refreshRequested: "refreshRequested" }, host: { listeners: { "document:keydown": "onKeydown($event)", "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "anchor", first: true, predicate: ["badgeEl"], descendants: true, read: ElementRef }, { propertyName: "popup", first: true, predicate: ["popupContent"], descendants: true, read: ElementRef }], ngImport: i0, template: `
|
|
5285
|
+
@if (currentTenantId) {
|
|
5286
|
+
<div #badgeEl class="tenant-badge" [class.denied]="isDenied" (click)="onToggle()">
|
|
5287
|
+
<span class="tenant-icon">{{ isDenied ? '\u26A0' : '\u25C6' }}</span>
|
|
5288
|
+
<span class="tenant-name">{{ currentTenantId }}</span>
|
|
5289
|
+
@if (isDenied) {
|
|
5290
|
+
<span class="denied-label">NO ACCESS</span>
|
|
5291
|
+
}
|
|
5292
|
+
</div>
|
|
5293
|
+
|
|
5294
|
+
@if (showPopup && !isDenied) {
|
|
5295
|
+
<kendo-popup #popupContent [anchor]="badgeEl"
|
|
5296
|
+
(anchorViewportLeave)="showPopup = false">
|
|
5297
|
+
<div class="tenant-popup">
|
|
5298
|
+
<div class="tenant-popup-header">
|
|
5299
|
+
<span>Switch Tenant</span>
|
|
5300
|
+
<button kendoButton fillMode="flat" size="small" class="refresh-btn"
|
|
5301
|
+
[disabled]="isRefreshing"
|
|
5302
|
+
title="Refresh tenant list"
|
|
5303
|
+
(click)="onRefresh($event)">
|
|
5304
|
+
<kendo-svgicon [icon]="refreshIcon" size="small"
|
|
5305
|
+
[class.spinning]="isRefreshing"></kendo-svgicon>
|
|
5306
|
+
</button>
|
|
5307
|
+
</div>
|
|
5308
|
+
<ul class="tenant-list">
|
|
5309
|
+
@for (tenant of allowedTenants; track tenant) {
|
|
5310
|
+
<li class="tenant-list-item" [class.active]="tenant === currentTenantId"
|
|
5311
|
+
(click)="onSelectTenant(tenant)">
|
|
5312
|
+
<span class="tenant-list-icon">◆</span>
|
|
5313
|
+
<span>{{ tenant }}</span>
|
|
5314
|
+
</li>
|
|
5315
|
+
}
|
|
5316
|
+
</ul>
|
|
5317
|
+
</div>
|
|
5318
|
+
</kendo-popup>
|
|
5319
|
+
}
|
|
5320
|
+
}
|
|
5321
|
+
`, isInline: true, styles: [":host{display:inline-flex;align-items:center}.tenant-badge{display:flex;align-items:center;gap:8px;padding:6px 14px;background:var(--mm-tenant-switcher-bg, var(--kendo-color-surface, transparent));border:1px solid var(--mm-tenant-switcher-border, var(--kendo-color-border, #dee2e6));border-radius:var(--mm-tenant-switcher-radius, 4px 16px 16px 4px);box-shadow:var(--mm-tenant-switcher-shadow, none);cursor:pointer;transition:all .2s ease}.tenant-badge:hover{background:var(--mm-tenant-switcher-bg-hover, var(--kendo-color-base-hover, rgba(0, 0, 0, .04)));box-shadow:var(--mm-tenant-switcher-shadow-hover, var(--mm-tenant-switcher-shadow, none))}.tenant-icon{font-size:.7rem;color:var(--mm-tenant-switcher-accent, var(--kendo-color-primary, #ff6358));animation:var(--mm-tenant-switcher-icon-animation, none)}.tenant-name{font-family:var(--mm-tenant-switcher-font, inherit);font-size:.85rem;font-weight:600;letter-spacing:1px;color:var(--mm-tenant-switcher-accent, var(--kendo-color-primary, #ff6358));text-transform:uppercase;text-shadow:var(--mm-tenant-switcher-text-shadow, none)}.denied{background:var(--mm-tenant-switcher-denied-bg, var(--mm-tenant-switcher-bg, var(--kendo-color-surface, transparent)));border-color:var(--mm-tenant-switcher-denied-border, var(--kendo-color-error, #d9534f));box-shadow:var(--mm-tenant-switcher-denied-shadow, none)}.denied .tenant-icon,.denied .tenant-name{color:var(--mm-tenant-switcher-denied-accent, var(--kendo-color-error, #d9534f));text-shadow:var(--mm-tenant-switcher-denied-text-shadow, none)}.denied-label{font-family:var(--mm-tenant-switcher-font, inherit);font-size:.55rem;font-weight:700;letter-spacing:1px;color:var(--mm-tenant-switcher-denied-accent, var(--kendo-color-error, #d9534f));background:var(--mm-tenant-switcher-denied-label-bg, color-mix(in srgb, var(--kendo-color-error, #d9534f) 15%, transparent));padding:2px 6px;border-radius:3px}.tenant-popup{min-width:220px;padding:8px 0;background:var(--kendo-color-surface, #fff);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.tenant-popup-header{display:flex;align-items:center;justify-content:space-between;padding:8px 16px;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #666);border-bottom:1px solid var(--kendo-color-border, #dee2e6);margin-bottom:4px}.refresh-btn{padding:2px;min-width:unset}.spinning{animation:spin .8s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.tenant-list{list-style:none;margin:0;padding:0}.tenant-list-item{display:flex;align-items:center;gap:10px;padding:8px 16px;cursor:pointer;font-size:.85rem;transition:background .15s ease}.tenant-list-item:hover{background:var(--kendo-color-base-hover, rgba(0, 0, 0, .04))}.tenant-list-item.active{color:var(--kendo-color-primary, #ff6358);font-weight:600}.tenant-list-icon{font-size:.5rem;color:var(--kendo-color-subtle, #666)}.tenant-list-item.active .tenant-list-icon{color:var(--kendo-color-primary, #ff6358)}@keyframes mm-icon-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.1)}}\n"], dependencies: [{ kind: "component", type: PopupComponent, selector: "kendo-popup", inputs: ["animate", "anchor", "anchorAlign", "collision", "popupAlign", "copyAnchorStyles", "popupClass", "positionMode", "offset", "margin"], outputs: ["anchorViewportLeave", "close", "open", "positionChange"], exportAs: ["kendo-popup"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: SVGIconComponent, selector: "kendo-svg-icon, kendo-svgicon", inputs: ["icon"], exportAs: ["kendoSVGIcon"] }] });
|
|
5322
|
+
}
|
|
5323
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: TenantSwitcherComponent, decorators: [{
|
|
5324
|
+
type: Component,
|
|
5325
|
+
args: [{ selector: 'mm-tenant-switcher', standalone: true, imports: [
|
|
5326
|
+
PopupComponent,
|
|
5327
|
+
ButtonComponent,
|
|
5328
|
+
SVGIconComponent
|
|
5329
|
+
], template: `
|
|
5330
|
+
@if (currentTenantId) {
|
|
5331
|
+
<div #badgeEl class="tenant-badge" [class.denied]="isDenied" (click)="onToggle()">
|
|
5332
|
+
<span class="tenant-icon">{{ isDenied ? '\u26A0' : '\u25C6' }}</span>
|
|
5333
|
+
<span class="tenant-name">{{ currentTenantId }}</span>
|
|
5334
|
+
@if (isDenied) {
|
|
5335
|
+
<span class="denied-label">NO ACCESS</span>
|
|
5336
|
+
}
|
|
5337
|
+
</div>
|
|
5338
|
+
|
|
5339
|
+
@if (showPopup && !isDenied) {
|
|
5340
|
+
<kendo-popup #popupContent [anchor]="badgeEl"
|
|
5341
|
+
(anchorViewportLeave)="showPopup = false">
|
|
5342
|
+
<div class="tenant-popup">
|
|
5343
|
+
<div class="tenant-popup-header">
|
|
5344
|
+
<span>Switch Tenant</span>
|
|
5345
|
+
<button kendoButton fillMode="flat" size="small" class="refresh-btn"
|
|
5346
|
+
[disabled]="isRefreshing"
|
|
5347
|
+
title="Refresh tenant list"
|
|
5348
|
+
(click)="onRefresh($event)">
|
|
5349
|
+
<kendo-svgicon [icon]="refreshIcon" size="small"
|
|
5350
|
+
[class.spinning]="isRefreshing"></kendo-svgicon>
|
|
5351
|
+
</button>
|
|
5352
|
+
</div>
|
|
5353
|
+
<ul class="tenant-list">
|
|
5354
|
+
@for (tenant of allowedTenants; track tenant) {
|
|
5355
|
+
<li class="tenant-list-item" [class.active]="tenant === currentTenantId"
|
|
5356
|
+
(click)="onSelectTenant(tenant)">
|
|
5357
|
+
<span class="tenant-list-icon">◆</span>
|
|
5358
|
+
<span>{{ tenant }}</span>
|
|
5359
|
+
</li>
|
|
5360
|
+
}
|
|
5361
|
+
</ul>
|
|
5362
|
+
</div>
|
|
5363
|
+
</kendo-popup>
|
|
5364
|
+
}
|
|
5365
|
+
}
|
|
5366
|
+
`, styles: [":host{display:inline-flex;align-items:center}.tenant-badge{display:flex;align-items:center;gap:8px;padding:6px 14px;background:var(--mm-tenant-switcher-bg, var(--kendo-color-surface, transparent));border:1px solid var(--mm-tenant-switcher-border, var(--kendo-color-border, #dee2e6));border-radius:var(--mm-tenant-switcher-radius, 4px 16px 16px 4px);box-shadow:var(--mm-tenant-switcher-shadow, none);cursor:pointer;transition:all .2s ease}.tenant-badge:hover{background:var(--mm-tenant-switcher-bg-hover, var(--kendo-color-base-hover, rgba(0, 0, 0, .04)));box-shadow:var(--mm-tenant-switcher-shadow-hover, var(--mm-tenant-switcher-shadow, none))}.tenant-icon{font-size:.7rem;color:var(--mm-tenant-switcher-accent, var(--kendo-color-primary, #ff6358));animation:var(--mm-tenant-switcher-icon-animation, none)}.tenant-name{font-family:var(--mm-tenant-switcher-font, inherit);font-size:.85rem;font-weight:600;letter-spacing:1px;color:var(--mm-tenant-switcher-accent, var(--kendo-color-primary, #ff6358));text-transform:uppercase;text-shadow:var(--mm-tenant-switcher-text-shadow, none)}.denied{background:var(--mm-tenant-switcher-denied-bg, var(--mm-tenant-switcher-bg, var(--kendo-color-surface, transparent)));border-color:var(--mm-tenant-switcher-denied-border, var(--kendo-color-error, #d9534f));box-shadow:var(--mm-tenant-switcher-denied-shadow, none)}.denied .tenant-icon,.denied .tenant-name{color:var(--mm-tenant-switcher-denied-accent, var(--kendo-color-error, #d9534f));text-shadow:var(--mm-tenant-switcher-denied-text-shadow, none)}.denied-label{font-family:var(--mm-tenant-switcher-font, inherit);font-size:.55rem;font-weight:700;letter-spacing:1px;color:var(--mm-tenant-switcher-denied-accent, var(--kendo-color-error, #d9534f));background:var(--mm-tenant-switcher-denied-label-bg, color-mix(in srgb, var(--kendo-color-error, #d9534f) 15%, transparent));padding:2px 6px;border-radius:3px}.tenant-popup{min-width:220px;padding:8px 0;background:var(--kendo-color-surface, #fff);border:1px solid var(--kendo-color-border, #dee2e6);border-radius:4px}.tenant-popup-header{display:flex;align-items:center;justify-content:space-between;padding:8px 16px;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--kendo-color-subtle, #666);border-bottom:1px solid var(--kendo-color-border, #dee2e6);margin-bottom:4px}.refresh-btn{padding:2px;min-width:unset}.spinning{animation:spin .8s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.tenant-list{list-style:none;margin:0;padding:0}.tenant-list-item{display:flex;align-items:center;gap:10px;padding:8px 16px;cursor:pointer;font-size:.85rem;transition:background .15s ease}.tenant-list-item:hover{background:var(--kendo-color-base-hover, rgba(0, 0, 0, .04))}.tenant-list-item.active{color:var(--kendo-color-primary, #ff6358);font-weight:600}.tenant-list-icon{font-size:.5rem;color:var(--kendo-color-subtle, #666)}.tenant-list-item.active .tenant-list-icon{color:var(--kendo-color-primary, #ff6358)}@keyframes mm-icon-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.1)}}\n"] }]
|
|
5367
|
+
}], propDecorators: { currentTenantId: [{
|
|
5368
|
+
type: Input
|
|
5369
|
+
}], allowedTenants: [{
|
|
5370
|
+
type: Input
|
|
5371
|
+
}], isDenied: [{
|
|
5372
|
+
type: Input
|
|
5373
|
+
}], tenantSelected: [{
|
|
5374
|
+
type: Output
|
|
5375
|
+
}], refreshRequested: [{
|
|
5376
|
+
type: Output
|
|
5377
|
+
}], anchor: [{
|
|
5378
|
+
type: ViewChild,
|
|
5379
|
+
args: ['badgeEl', { read: ElementRef }]
|
|
5380
|
+
}], popup: [{
|
|
5381
|
+
type: ViewChild,
|
|
5382
|
+
args: ['popupContent', { read: ElementRef }]
|
|
5383
|
+
}], onKeydown: [{
|
|
5384
|
+
type: HostListener,
|
|
5385
|
+
args: ['document:keydown', ['$event']]
|
|
5386
|
+
}], onDocumentClick: [{
|
|
5387
|
+
type: HostListener,
|
|
5388
|
+
args: ['document:click', ['$event']]
|
|
5389
|
+
}] } });
|
|
5390
|
+
|
|
5158
5391
|
/*
|
|
5159
5392
|
* Public API Surface of octo-ui
|
|
5160
5393
|
*/
|
|
@@ -5178,5 +5411,5 @@ function provideOctoUi() {
|
|
|
5178
5411
|
* Generated bundle index. Do not edit.
|
|
5179
5412
|
*/
|
|
5180
5413
|
|
|
5181
|
-
export { AttributeSelectorDialogComponent, AttributeSelectorDialogService, AttributeSortSelectorDialogComponent, AttributeSortSelectorDialogService, AttributeValueTypeDto, CkTypeSelectorDialogComponent, CkTypeSelectorDialogService, CkTypeSelectorInputComponent, DefaultPropertyCategory, EntityIdInfoComponent, FieldFilterEditorComponent, OctoGraphQlDataSource, OctoGraphQlHierarchyDataSource, OctoLoaderComponent, PropertyConverterService, PropertyDisplayMode, PropertyGridComponent, PropertyValueDisplayComponent, RuntimeEntityVariableDialogComponent, RuntimeEntityVariableDialogService, provideOctoUi };
|
|
5414
|
+
export { AttributeSelectorDialogComponent, AttributeSelectorDialogService, AttributeSortSelectorDialogComponent, AttributeSortSelectorDialogService, AttributeValueTypeDto, CkTypeSelectorDialogComponent, CkTypeSelectorDialogService, CkTypeSelectorInputComponent, DefaultPropertyCategory, EntityIdInfoComponent, FieldFilterEditorComponent, OctoGraphQlDataSource, OctoGraphQlHierarchyDataSource, OctoLoaderComponent, PropertyConverterService, PropertyDisplayMode, PropertyGridComponent, PropertyValueDisplayComponent, RuntimeEntityVariableDialogComponent, RuntimeEntityVariableDialogService, TenantSwitcherComponent, provideOctoUi };
|
|
5182
5415
|
//# sourceMappingURL=meshmakers-octo-ui.mjs.map
|