@acorex/platform 20.6.0-next.20 → 20.6.0-next.22

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.
@@ -4,9 +4,9 @@ import { AXTranslationService, AXTranslationModule } from '@acorex/core/translat
4
4
  import * as i4 from '@acorex/platform/common';
5
5
  import { AXPSettingService, AXPFilterOperatorMiddlewareService, AXPEntityCommandScope, getEntityInfo, AXPRefreshEvent, AXPReloadEvent, AXPCommonSettings, AXPCleanNestedFilters, AXPWorkflowNavigateAction, AXPToastAction, AXP_SEARCH_DEFINITION_PROVIDER } from '@acorex/platform/common';
6
6
  import * as i1$2 from '@acorex/platform/core';
7
- import { AXPDeviceService, AXPBroadcastEventService, resolveActionLook, AXPExpressionEvaluatorService, AXPDistributedEventListenerService, AXPPlatformScope, extractValue, setSmart, getChangedPaths, AXPSystemActionType } from '@acorex/platform/core';
7
+ import { AXPDeviceService, AXPBroadcastEventService, resolveActionLook, AXPExpressionEvaluatorService, AXPDistributedEventListenerService, AXPPlatformScope, AXHighlightService, extractValue, setSmart, getChangedPaths, AXPSystemActionType } from '@acorex/platform/core';
8
8
  import * as i0 from '@angular/core';
9
- import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, input, viewChild, signal, ElementRef, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, createComponent, computed, afterNextRender, ViewEncapsulation, ChangeDetectorRef, effect, viewChildren, linkedSignal, untracked, HostBinding, ViewChild, NgModule } from '@angular/core';
9
+ import { InjectionToken, inject, Injector, runInInjectionContext, Injectable, input, viewChild, signal, ElementRef, ChangeDetectionStrategy, Component, ApplicationRef, EnvironmentInjector, createComponent, computed, effect, Input, afterNextRender, ViewEncapsulation, ChangeDetectorRef, viewChildren, linkedSignal, untracked, HostBinding, ViewChild, NgModule } from '@angular/core';
10
10
  import { Subject, takeUntil } from 'rxjs';
11
11
  import { AXPLayoutBuilderService } from '@acorex/platform/layout/builder';
12
12
  import { merge, castArray, get, cloneDeep, set, orderBy, isNil, isEqual, isEmpty, sortBy } from 'lodash-es';
@@ -33,6 +33,7 @@ import { AXDialogService } from '@acorex/components/dialog';
33
33
  import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
34
34
  import { AXPopupService } from '@acorex/components/popup';
35
35
  import { AXPlatform } from '@acorex/core/platform';
36
+ import { AXCheckBoxModule } from '@acorex/components/check-box';
36
37
  import * as i2$1 from '@acorex/components/decorators';
37
38
  import { AXDecoratorModule } from '@acorex/components/decorators';
38
39
  import { AXBasePageComponent } from '@acorex/components/page';
@@ -41,6 +42,9 @@ import { AXSearchBoxModule, AXSearchBoxComponent } from '@acorex/components/sear
41
42
  import * as i4$1 from '@acorex/components/skeleton';
42
43
  import { AXSkeletonModule } from '@acorex/components/skeleton';
43
44
  import { AXTreeViewComponent } from '@acorex/components/tree-view';
45
+ import { AXPStateMessageComponent, AXPDataSelectorService, AXPWidgetPropertyViewerComponent } from '@acorex/platform/layout/components';
46
+ import * as i1$1 from '@angular/forms';
47
+ import { FormsModule } from '@angular/forms';
44
48
  import * as i2$2 from '@acorex/components/badge';
45
49
  import { AXBadgeModule } from '@acorex/components/badge';
46
50
  import * as i5$1 from '@acorex/components/form';
@@ -49,15 +53,12 @@ import { AXValidationModule } from '@acorex/core/validation';
49
53
  import { AXP_DISABLED_PROPERTY, AXP_ALLOW_CLEAR_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DATA_PROPERTY_GROUP, AXP_ALLOW_MULTIPLE_PROPERTY, AXP_NAME_PROPERTY, AXPFileUploaderWidgetService } from '@acorex/platform/layout/widgets';
50
54
  import * as i4$2 from '@acorex/components/dropdown';
51
55
  import { AXDropdownModule } from '@acorex/components/dropdown';
52
- import * as i1$1 from '@angular/forms';
53
- import { FormsModule } from '@angular/forms';
54
56
  import * as i7 from '@acorex/components/select-box';
55
57
  import { AXSelectBoxModule } from '@acorex/components/select-box';
56
58
  import * as i2$3 from '@acorex/components/text-box';
57
59
  import { AXTextBoxModule, AXTextBoxComponent } from '@acorex/components/text-box';
58
60
  import * as i6$1 from '@acorex/components/tag-box';
59
61
  import { AXTagBoxComponent, AXTagBoxModule } from '@acorex/components/tag-box';
60
- import { AXPDataSelectorService, AXPWidgetPropertyViewerComponent } from '@acorex/platform/layout/components';
61
62
  import { transform, isEqual as isEqual$1 } from 'lodash';
62
63
 
63
64
  function ensureListActions(ctx) {
@@ -725,9 +726,11 @@ class PropertyFilter {
725
726
  const entityProps = (entity.properties ?? []).slice();
726
727
  const nameToViewLayout = buildViewLayoutMap(iface.properties ?? []);
727
728
  const allowedNames = this.computeAllowedNames(entityProps.map((p) => p.name));
729
+ // Calculate recommended dialog size based on form complexity
730
+ const calculatedSize = this.calculateRecommendedDialogSize(sections, entityProps, nameToViewLayout, allowedNames);
728
731
  const dialog = this.layoutBuilder.create().dialog((d) => {
729
732
  d.setTitle(title);
730
- d.setSize(this.externalSize ?? (this.deviceService.isMobileDevice() ? 'full' : 'md'));
733
+ d.setSize(this.externalSize ?? calculatedSize);
731
734
  d.setCloseButton(true);
732
735
  d.content((layout) => {
733
736
  // Default mode: 'view' for single, 'edit' for create/update
@@ -759,7 +762,7 @@ class PropertyFilter {
759
762
  fs.formField(prop.title, (field) => {
760
763
  // Path & field-level visibility/readonly
761
764
  field.path(fieldPath);
762
- if (prop.schema?.visible) {
765
+ if (prop.schema?.visible !== undefined) {
763
766
  field.visible(prop.schema?.visible);
764
767
  }
765
768
  if (prop.schema?.readonly !== undefined) {
@@ -840,6 +843,78 @@ class PropertyFilter {
840
843
  }
841
844
  return new Set(allNames);
842
845
  }
846
+ /**
847
+ * Calculates the recommended dialog size based on form complexity.
848
+ * Considers number of sections, properties, and average field width.
849
+ *
850
+ * @param sections - Interface sections to display
851
+ * @param entityProps - All entity properties
852
+ * @param nameToViewLayout - Map of property names to their view layout configurations
853
+ * @param allowedNames - Set of property names that should be displayed (after filtering)
854
+ * @returns Recommended dialog size ('full' | 'lg' | 'md')
855
+ */
856
+ calculateRecommendedDialogSize(sections, entityProps, nameToViewLayout, allowedNames) {
857
+ // Mobile devices always use full screen
858
+ if (this.deviceService.isMobileDevice()) {
859
+ return 'full';
860
+ }
861
+ // Calculate number of visible properties
862
+ const visibleProperties = entityProps.filter((p) => allowedNames.has(p.name) && nameToViewLayout.has(p.name));
863
+ const visiblePropertyCount = visibleProperties.length;
864
+ // Calculate average colSpan to determine field width
865
+ // colSpan determines how many columns a field occupies in a 12-column grid
866
+ // Examples:
867
+ // - colSpan = 12 → 1 field per row (full width)
868
+ // - colSpan = 6 → 2 fields per row (half width each)
869
+ // - colSpan = 4 → 3 fields per row (one-third width each)
870
+ // - colSpan = 3 → 4 fields per row (one-quarter width each)
871
+ let totalColSpan = 0;
872
+ let propertiesWithLayout = 0;
873
+ let hasColSpan3 = false; // Track if any field has colSpan = 3
874
+ for (const prop of visibleProperties) {
875
+ const viewLayout = nameToViewLayout.get(prop.name);
876
+ const positions = viewLayout?.layout?.positions;
877
+ if (positions) {
878
+ // Get colSpan from the largest available breakpoint
879
+ const colSpan = positions.lg?.colSpan ?? positions.xl?.colSpan ?? positions.md?.colSpan ?? positions.sm?.colSpan ?? 12; // default: full width
880
+ totalColSpan += colSpan;
881
+ propertiesWithLayout++;
882
+ // Check if this field has colSpan = 3
883
+ if (colSpan <= 3) {
884
+ hasColSpan3 = true;
885
+ }
886
+ }
887
+ else {
888
+ // If no layout defined, assume full width (12 columns)
889
+ totalColSpan += 12;
890
+ propertiesWithLayout++;
891
+ }
892
+ }
893
+ // Average colSpan: lower value = more fields per row, higher value = fewer fields per row
894
+ const avgColSpan = propertiesWithLayout > 0 ? totalColSpan / propertiesWithLayout : 12;
895
+ // Decision logic:
896
+ // - 10+ properties → complex form → needs 'lg'
897
+ // - avgColSpan <= 4 → 3+ fields per row → needs 'lg' (more horizontal space needed)
898
+ // - hasColSpan3 && avgColSpan <= 6 → row can sum to 12 with colSpan=3 (e.g., 9+3, 5+4+3, etc.) → needs 'lg'
899
+ // - Otherwise → 'md' is sufficient
900
+ if (visiblePropertyCount >= 10) {
901
+ return 'lg';
902
+ }
903
+ // If average colSpan <= 4, it means we can fit 3+ fields per row (12/4 = 3)
904
+ // This requires more horizontal space, so use 'lg'
905
+ if (avgColSpan <= 4) {
906
+ return 'lg';
907
+ }
908
+ // If there's a field with colSpan = 3 and avgColSpan <= 6,
909
+ // it means rows can sum to 12 with multiple fields including the colSpan=3 field
910
+ // (e.g., 9+3=12, 5+4+3=12, 4+3+3+2=12, etc.)
911
+ // This needs 'lg' for better horizontal space to accommodate the layout
912
+ if (hasColSpan3 && avgColSpan <= 6) {
913
+ return 'lg';
914
+ }
915
+ // For other cases (including full-width fields), 'md' is sufficient
916
+ return 'md';
917
+ }
843
918
  }
844
919
  //#endregion
845
920
  //#region ---- Helpers ----
@@ -946,6 +1021,7 @@ class AXPCreateEntityCommand {
946
1021
  }
947
1022
  async execute(input) {
948
1023
  const excludeProperties = input['excludeProperties'];
1024
+ const dialogSize = input['dialogSize'];
949
1025
  const { entity, entityInfo, data } = input.__context__;
950
1026
  const [moduleName, entityName] = (entity || '').split('.');
951
1027
  if (!moduleName || !entityName) {
@@ -972,6 +1048,9 @@ class AXPCreateEntityCommand {
972
1048
  const translatedTitle = await this.translationService.translateAsync(entityInfo.title);
973
1049
  chain = chain.title(`${createText} ${translatedTitle}`);
974
1050
  }
1051
+ if (dialogSize) {
1052
+ chain.size(dialogSize);
1053
+ }
975
1054
  dialogRef = await chain.show();
976
1055
  if (dialogRef.action() == 'cancel') {
977
1056
  dialogRef.close();
@@ -1063,6 +1142,7 @@ class AXPUpdateEntityCommand {
1063
1142
  //#region ---- Command Execution ----
1064
1143
  async execute(input) {
1065
1144
  const excludeProperties = input['excludeProperties'];
1145
+ const dialogSize = input['dialogSize'];
1066
1146
  const { entity, entityInfo, data } = input.__context__;
1067
1147
  const [moduleName, entityName] = (entity || '').split('.');
1068
1148
  if (!moduleName || !entityName) {
@@ -1099,6 +1179,9 @@ class AXPUpdateEntityCommand {
1099
1179
  const translatedTitle = await this.translationService.translateAsync(entityInfo.title);
1100
1180
  chain = chain.title(`${editText} ${translatedTitle}`);
1101
1181
  }
1182
+ if (dialogSize) {
1183
+ chain.size(dialogSize);
1184
+ }
1102
1185
  dialogRef = await chain.show();
1103
1186
  if (dialogRef.action() === 'cancel') {
1104
1187
  dialogRef.close();
@@ -5815,13 +5898,14 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
5815
5898
  //#region ---- Services & Dependencies ----
5816
5899
  this.categoryTreeService = inject(AXPCategoryTreeService);
5817
5900
  this.translationService = inject(AXTranslationService);
5901
+ this.highlightService = inject(AXHighlightService);
5818
5902
  //#endregion
5819
5903
  //#region ---- Properties (Set by popup service) ----
5820
5904
  this.entityKey = signal('', ...(ngDevMode ? [{ debugName: "entityKey" }] : []));
5821
5905
  this.textField = signal('title', ...(ngDevMode ? [{ debugName: "textField" }] : []));
5822
5906
  this.valueField = signal('id', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
5823
5907
  this.allowMultiple = signal(false, ...(ngDevMode ? [{ debugName: "allowMultiple" }] : []));
5824
- this.selectionBehavior = signal('leaf', ...(ngDevMode ? [{ debugName: "selectionBehavior" }] : []));
5908
+ this.selectionBehavior = signal('all', ...(ngDevMode ? [{ debugName: "selectionBehavior" }] : []));
5825
5909
  this.selectedValues = signal([], ...(ngDevMode ? [{ debugName: "selectedValues" }] : []));
5826
5910
  this.searchPlaceholder = signal('@general:terms.interface.category.search.placeholder', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
5827
5911
  this.excludedNodeId = signal(undefined, ...(ngDevMode ? [{ debugName: "excludedNodeId" }] : [])); // Node ID to disable
@@ -5987,11 +6071,11 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
5987
6071
  return;
5988
6072
  }
5989
6073
  // Prevent concurrent searches
5990
- if (this.isSearching() && this.currentSearchTerm !== null) {
5991
- if (this.currentSearchTerm === searchTerm) {
5992
- return;
5993
- }
5994
- }
6074
+ // if (this.isSearching() && this.currentSearchTerm !== null) {
6075
+ // if (this.currentSearchTerm === searchTerm) {
6076
+ // return;
6077
+ // }
6078
+ // }
5995
6079
  this.searchValue.set(event.value ?? '');
5996
6080
  this.currentSearchTerm = searchTerm;
5997
6081
  const treeComponent = this.tree();
@@ -6031,8 +6115,12 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
6031
6115
  }
6032
6116
  if (!searchResults || searchResults.length === 0) {
6033
6117
  this.matchingNodeIds.clear();
6118
+ this.relevantNodeIds.clear();
6034
6119
  this.searchResultCount.set(0);
6035
6120
  await this.updateTranslatedMessages(0, searchTerm);
6121
+ // Clear highlighting and reload tree to show all nodes
6122
+ this.highlightService.clear();
6123
+ await treeComponent.reloadData();
6036
6124
  return;
6037
6125
  }
6038
6126
  // Store matching node IDs from search results
@@ -6085,11 +6173,25 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
6085
6173
  }
6086
6174
  }
6087
6175
  }
6176
+ // Step 5: Apply highlighting after tree is rendered
6177
+ // Use setTimeout to ensure DOM is updated after tree reload
6178
+ setTimeout(() => {
6179
+ if (this.searchValue().trim()) {
6180
+ this.highlightService.highlight('ax-tree-view .ax-truncate', this.searchValue().trim());
6181
+ }
6182
+ }, 100);
6088
6183
  }
6089
6184
  catch (error) {
6090
6185
  console.error('Error searching categories:', error);
6091
6186
  this.matchingNodeIds.clear();
6187
+ this.relevantNodeIds.clear();
6092
6188
  this.searchResultCount.set(0);
6189
+ this.highlightService.clear();
6190
+ // Reload tree to clear any filters
6191
+ const treeComponent = this.tree();
6192
+ if (treeComponent) {
6193
+ await treeComponent.reloadData();
6194
+ }
6093
6195
  }
6094
6196
  finally {
6095
6197
  if (this.currentSearchTerm === searchTerm) {
@@ -6356,6 +6458,8 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
6356
6458
  this.isSearching.set(false);
6357
6459
  this.matchingNodeIds.clear();
6358
6460
  this.relevantNodeIds.clear();
6461
+ // Clear highlighting
6462
+ this.highlightService.clear();
6359
6463
  const treeComponent = this.tree();
6360
6464
  if (!treeComponent) {
6361
6465
  this.expandedNodesBeforeSearch = [];
@@ -6452,6 +6556,36 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
6452
6556
  isMatchingNode(nodeId) {
6453
6557
  return this.matchingNodeIds.has(nodeId);
6454
6558
  }
6559
+ /**
6560
+ * Checks if a node is currently selected
6561
+ */
6562
+ isNodeSelected(nodeId) {
6563
+ if (!nodeId || nodeId === 'all') {
6564
+ return false;
6565
+ }
6566
+ const id = String(nodeId);
6567
+ return this.selectedNodeIds().includes(id);
6568
+ }
6569
+ /**
6570
+ * Handles checkbox change event to toggle node selection
6571
+ */
6572
+ // protected handleCheckboxChange(nodeId: string | number | undefined, checked: boolean): void {
6573
+ // if (!nodeId || nodeId === 'all') {
6574
+ // return;
6575
+ // }
6576
+ // const id = String(nodeId);
6577
+ // const treeComponent = this.tree();
6578
+ // if (!treeComponent) {
6579
+ // return;
6580
+ // }
6581
+ // if (checked) {
6582
+ // // Select the node
6583
+ // treeComponent.selectNode(id);
6584
+ // } else {
6585
+ // // Deselect the node
6586
+ // treeComponent.deselectNode(id);
6587
+ // }
6588
+ // }
6455
6589
  //#endregion
6456
6590
  async updateSelectedNodes(selectedIds) {
6457
6591
  if (!selectedIds || selectedIds.length === 0) {
@@ -6823,23 +6957,18 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
6823
6957
  <div class="ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1">
6824
6958
  @if (searchResultCount() > 0) {
6825
6959
  <span>{{ resultsFoundText() }}</span>
6826
- } @else {
6827
- <span>{{ '@general:terms.interface.category.search.no-results' | translate | async }}</span>
6828
6960
  }
6829
6961
  </div>
6830
6962
  }
6831
6963
  </div>
6832
6964
  @if (showNoSearchResults()) {
6833
- <div class="ax-flex-1 ax-flex ax-items-center ax-justify-center ax-p-4">
6834
- <div class="ax-text-center ax-text-muted">
6835
- <ax-icon class="fa-light fa-search ax-text-4xl ax-mb-2 ax-opacity-50"></ax-icon>
6836
- <p class="ax-text-sm">
6837
- {{ '@general:terms.interface.category.search.no-results-found.title' | translate | async }}
6838
- </p>
6839
- <p class="ax-text-xs ax-opacity-70">
6840
- {{ '@general:terms.interface.category.search.no-results-found.description' | translate | async }}
6841
- </p>
6842
- </div>
6965
+ <div class="ax-flex-1 ax-flex ax-items-center ax-justify-center">
6966
+ <axp-state-message
6967
+ icon="fa-light fa-search"
6968
+ [title]="'@general:terms.interface.category.search.no-results-found.title'"
6969
+ [description]="'@general:terms.interface.category.search.no-results-found.description'"
6970
+ >
6971
+ </axp-state-message>
6843
6972
  </div>
6844
6973
  } @else {
6845
6974
  <div class="ax-flex-1 ax-overflow-auto ax-p-4">
@@ -6862,18 +6991,18 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
6862
6991
  <ng-template #itemTemplate let-node="node" let-level="level">
6863
6992
  @if (node) {
6864
6993
  @let item = node.data || node;
6865
- @let isMatch = isMatchingNode(node.id);
6866
- <div
6867
- class="ax-flex ax-items-center ax-gap-2 ax-w-full ax-overflow-hidden ax-p-2 ax-pe-0"
6868
- [class.ax-bg-secondary-100]="isMatch"
6869
- [class.ax-rounded]="isMatch"
6870
- [class.ax-px-1]="isMatch"
6871
- >
6994
+ <div class="ax-flex ax-items-center ax-gap-2 ax-w-full ax-overflow-hidden ax-p-2 ax-pe-0">
6995
+ <!-- <ax-check-box
6996
+ [ngModel]="isNodeSelected(node.id)"
6997
+ (onValueChanged)="handleCheckboxChange(node.id, $event.value)"
6998
+ (click)="$event.stopPropagation()"
6999
+ [disabled]="node.disabled || node.id === 'all'"
7000
+ ></ax-check-box> -->
6872
7001
  <ax-icon
6873
7002
  class="fas fa-folder"
6874
7003
  [style.color]="item.color ?? 'rgba(var(--ax-sys-color-warning-500), 1)'"
6875
7004
  ></ax-icon>
6876
- <span class="ax-truncate" [class.ax-font-semibold]="isMatch">{{ node.title }}</span>
7005
+ <span class="ax-truncate">{{ node.title }}</span>
6877
7006
  </div>
6878
7007
  }
6879
7008
  </ng-template>
@@ -6881,8 +7010,13 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
6881
7010
  }
6882
7011
  </div>
6883
7012
  } @else {
6884
- <div class="ax-p-4 ax-text-center ax-text-muted">
6885
- <span>---</span>
7013
+ <div class="ax-flex-1 ax-flex ax-items-center ax-justify-center">
7014
+ <axp-state-message
7015
+ icon="fa-light fa-folder-open"
7016
+ [title]="'@general:terms.interface.category.search.no-records.title'"
7017
+ [description]="'@general:terms.interface.category.search.no-records.description'"
7018
+ >
7019
+ </axp-state-message>
6886
7020
  </div>
6887
7021
  }
6888
7022
  </div>
@@ -6897,11 +7031,12 @@ class AXPEntityCategoryTreeSelectorComponent extends AXBasePageComponent {
6897
7031
  look="solid"
6898
7032
  color="primary"
6899
7033
  [text]="'@general:actions.ok.title' | translate | async"
7034
+ [disabled]="selectedNodeIds().length === 0"
6900
7035
  (onClick)="onConfirm()"
6901
7036
  ></ax-button>
6902
7037
  </ax-suffix>
6903
7038
  </ax-footer>
6904
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i3$2.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i4$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick"], outputs: ["datasourceChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7039
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i3$2.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i4$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick"], outputs: ["datasourceChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6905
7040
  }
6906
7041
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryTreeSelectorComponent, decorators: [{
6907
7042
  type: Component,
@@ -6932,23 +7067,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
6932
7067
  <div class="ax-text-xs ax-text-muted ax-flex ax-items-center ax-gap-1">
6933
7068
  @if (searchResultCount() > 0) {
6934
7069
  <span>{{ resultsFoundText() }}</span>
6935
- } @else {
6936
- <span>{{ '@general:terms.interface.category.search.no-results' | translate | async }}</span>
6937
7070
  }
6938
7071
  </div>
6939
7072
  }
6940
7073
  </div>
6941
7074
  @if (showNoSearchResults()) {
6942
- <div class="ax-flex-1 ax-flex ax-items-center ax-justify-center ax-p-4">
6943
- <div class="ax-text-center ax-text-muted">
6944
- <ax-icon class="fa-light fa-search ax-text-4xl ax-mb-2 ax-opacity-50"></ax-icon>
6945
- <p class="ax-text-sm">
6946
- {{ '@general:terms.interface.category.search.no-results-found.title' | translate | async }}
6947
- </p>
6948
- <p class="ax-text-xs ax-opacity-70">
6949
- {{ '@general:terms.interface.category.search.no-results-found.description' | translate | async }}
6950
- </p>
6951
- </div>
7075
+ <div class="ax-flex-1 ax-flex ax-items-center ax-justify-center">
7076
+ <axp-state-message
7077
+ icon="fa-light fa-search"
7078
+ [title]="'@general:terms.interface.category.search.no-results-found.title'"
7079
+ [description]="'@general:terms.interface.category.search.no-results-found.description'"
7080
+ >
7081
+ </axp-state-message>
6952
7082
  </div>
6953
7083
  } @else {
6954
7084
  <div class="ax-flex-1 ax-overflow-auto ax-p-4">
@@ -6971,18 +7101,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
6971
7101
  <ng-template #itemTemplate let-node="node" let-level="level">
6972
7102
  @if (node) {
6973
7103
  @let item = node.data || node;
6974
- @let isMatch = isMatchingNode(node.id);
6975
- <div
6976
- class="ax-flex ax-items-center ax-gap-2 ax-w-full ax-overflow-hidden ax-p-2 ax-pe-0"
6977
- [class.ax-bg-secondary-100]="isMatch"
6978
- [class.ax-rounded]="isMatch"
6979
- [class.ax-px-1]="isMatch"
6980
- >
7104
+ <div class="ax-flex ax-items-center ax-gap-2 ax-w-full ax-overflow-hidden ax-p-2 ax-pe-0">
7105
+ <!-- <ax-check-box
7106
+ [ngModel]="isNodeSelected(node.id)"
7107
+ (onValueChanged)="handleCheckboxChange(node.id, $event.value)"
7108
+ (click)="$event.stopPropagation()"
7109
+ [disabled]="node.disabled || node.id === 'all'"
7110
+ ></ax-check-box> -->
6981
7111
  <ax-icon
6982
7112
  class="fas fa-folder"
6983
7113
  [style.color]="item.color ?? 'rgba(var(--ax-sys-color-warning-500), 1)'"
6984
7114
  ></ax-icon>
6985
- <span class="ax-truncate" [class.ax-font-semibold]="isMatch">{{ node.title }}</span>
7115
+ <span class="ax-truncate">{{ node.title }}</span>
6986
7116
  </div>
6987
7117
  }
6988
7118
  </ng-template>
@@ -6990,8 +7120,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
6990
7120
  }
6991
7121
  </div>
6992
7122
  } @else {
6993
- <div class="ax-p-4 ax-text-center ax-text-muted">
6994
- <span>---</span>
7123
+ <div class="ax-flex-1 ax-flex ax-items-center ax-justify-center">
7124
+ <axp-state-message
7125
+ icon="fa-light fa-folder-open"
7126
+ [title]="'@general:terms.interface.category.search.no-records.title'"
7127
+ [description]="'@general:terms.interface.category.search.no-records.description'"
7128
+ >
7129
+ </axp-state-message>
6995
7130
  </div>
6996
7131
  }
6997
7132
  </div>
@@ -7006,6 +7141,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
7006
7141
  look="solid"
7007
7142
  color="primary"
7008
7143
  [text]="'@general:actions.ok.title' | translate | async"
7144
+ [disabled]="selectedNodeIds().length === 0"
7009
7145
  (onClick)="onConfirm()"
7010
7146
  ></ax-button>
7011
7147
  </ax-suffix>
@@ -7015,11 +7151,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
7015
7151
  imports: [
7016
7152
  CommonModule,
7017
7153
  AXButtonModule,
7154
+ AXCheckBoxModule,
7018
7155
  AXDecoratorModule,
7019
7156
  AXSearchBoxModule,
7020
7157
  AXSkeletonModule,
7021
7158
  AXTreeViewComponent,
7022
7159
  AXTranslationModule,
7160
+ AXPStateMessageComponent,
7161
+ FormsModule,
7023
7162
  ],
7024
7163
  }]
7025
7164
  }], propDecorators: { tree: [{ type: i0.ViewChild, args: ['tree', { isSignal: true }] }] } });
@@ -7027,177 +7166,275 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
7027
7166
  class AXPEntityCategoryWidgetColumnComponent extends AXPColumnWidgetComponent {
7028
7167
  constructor() {
7029
7168
  super(...arguments);
7030
- //#region ---- Dependencies ----
7169
+ //#region ---- Services & Dependencies ----
7031
7170
  this.entityDetailPopoverService = inject(AXPEntityDetailPopoverService);
7032
7171
  this.formatService = inject(AXFormatService);
7172
+ this.entityResolver = inject(AXPEntityResolver);
7033
7173
  //#endregion
7034
- //#region ---- View Children ----
7035
- this.moreButton = viewChild('moreButton', ...(ngDevMode ? [{ debugName: "moreButton" }] : []));
7036
- this.morePopover = viewChild('morePopover', ...(ngDevMode ? [{ debugName: "morePopover" }] : []));
7174
+ //#region ---- Inputs ----
7175
+ this.rawValueSignal = signal(null, ...(ngDevMode ? [{ debugName: "rawValueSignal" }] : []));
7037
7176
  //#endregion
7038
- //#region ---- Properties ----
7039
- this.host = inject(ElementRef);
7040
- this.valueField = this.options['valueField'] ?? 'id';
7041
- this.textField = this.options['textField'] ?? 'title';
7042
- this.entity = this.options['entity'] ?? '';
7043
- this.columnName = this.options['columnName'] ?? '';
7044
- this.maxVisible = this.options['maxVisible'] ?? 2;
7177
+ //#region ---- Computed Properties ----
7178
+ this.entity = computed(() => this.options['entity'] ?? '', ...(ngDevMode ? [{ debugName: "entity" }] : []));
7179
+ this.valueField = computed(() => this.options['valueField'] ?? 'id', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
7180
+ this.textField = computed(() => this.options['textField'] ?? 'title', ...(ngDevMode ? [{ debugName: "textField" }] : []));
7181
+ this.columnName = computed(() => this.options['columnName'] ?? '', ...(ngDevMode ? [{ debugName: "columnName" }] : []));
7182
+ this.defaultTextField = computed(() => {
7183
+ const textField = this.entityDef()?.formats.lookup ?? this.entityDef()?.properties.find((c) => c.name != 'id')?.name ?? 'title';
7184
+ return textField;
7185
+ }, ...(ngDevMode ? [{ debugName: "defaultTextField" }] : []));
7186
+ this.displayField = computed(() => {
7187
+ if (this.textField()) {
7188
+ return this.textField();
7189
+ }
7190
+ return this.defaultTextField();
7191
+ }, ...(ngDevMode ? [{ debugName: "displayField" }] : []));
7045
7192
  //#endregion
7046
- //#region ---- Signals ----
7047
- this.isMorePopoverOpen = signal(false, ...(ngDevMode ? [{ debugName: "isMorePopoverOpen" }] : []));
7193
+ //#region ---- Component State ----
7194
+ this.host = inject(ElementRef);
7195
+ this.entityDef = signal(null, ...(ngDevMode ? [{ debugName: "entityDef" }] : []));
7196
+ this.displayItems = signal([], ...(ngDevMode ? [{ debugName: "displayItems" }] : []));
7048
7197
  this.selectedItemIndex = signal(-1, ...(ngDevMode ? [{ debugName: "selectedItemIndex" }] : []));
7049
7198
  //#endregion
7050
- //#region ---- Computed Properties ----
7051
- this.displayItems = computed(() => isNil(this.rawValue)
7052
- ? []
7053
- : castArray(this.rawValue)
7054
- .map((item) => this.extractItem(item))
7055
- .filter((c) => c != null), ...(ngDevMode ? [{ debugName: "displayItems" }] : []));
7056
- this.allItems = computed(() => this.displayItems(), ...(ngDevMode ? [{ debugName: "allItems" }] : []));
7057
- this.visibleItems = computed(() => {
7058
- const items = this.allItems();
7059
- return items.slice(0, this.maxVisible);
7060
- }, ...(ngDevMode ? [{ debugName: "visibleItems" }] : []));
7061
- this.remainingItems = computed(() => {
7062
- const items = this.allItems();
7063
- return items.slice(this.maxVisible);
7064
- }, ...(ngDevMode ? [{ debugName: "remainingItems" }] : []));
7065
- this.hasMoreItems = computed(() => {
7066
- return this.allItems().length > this.maxVisible;
7067
- }, ...(ngDevMode ? [{ debugName: "hasMoreItems" }] : []));
7068
- this.remainingItemsCount = computed(() => {
7069
- return this.allItems().length - this.maxVisible;
7070
- }, ...(ngDevMode ? [{ debugName: "remainingItemsCount" }] : []));
7199
+ //#region ---- Effects ----
7200
+ this.efEntity = effect(async () => {
7201
+ const entityKey = this.entity();
7202
+ if (!entityKey) {
7203
+ return;
7204
+ }
7205
+ const [module, entity] = entityKey.split('.');
7206
+ if (!module || !entity) {
7207
+ return;
7208
+ }
7209
+ this.entityDef.set(await this.entityResolver.get(module, entity));
7210
+ }, ...(ngDevMode ? [{ debugName: "efEntity" }] : []));
7211
+ this.efDisplay = effect(async () => {
7212
+ const value = this.rawValueSignal();
7213
+ const entity = this.entityDef();
7214
+ // Wait for entity definition to be loaded before processing value
7215
+ if (!entity) {
7216
+ this.displayItems.set([]);
7217
+ return;
7218
+ }
7219
+ if (isNil(value)) {
7220
+ this.displayItems.set([]);
7221
+ }
7222
+ else {
7223
+ const items = castArray(value);
7224
+ const itemsWithPaths = await Promise.all(items.map((item) => this.extractItemWithPath(item)));
7225
+ this.displayItems.set(itemsWithPaths.filter((c) => c != null));
7226
+ }
7227
+ }, ...(ngDevMode ? [{ debugName: "efDisplay" }] : []));
7228
+ //#endregion
7229
+ //#region ---- Computed Properties (Derived) ----
7230
+ this.visibleItems = computed(() => this.displayItems(), ...(ngDevMode ? [{ debugName: "visibleItems" }] : []));
7231
+ }
7232
+ set rawValueInput(value) {
7233
+ this.rawValueSignal.set(value);
7071
7234
  }
7072
7235
  //#endregion
7073
7236
  //#region ---- Public Methods ----
7074
- showMoreItems() {
7075
- this.entityDetailPopoverService.hide();
7076
- this.openMorePopover();
7077
- }
7078
- onMorePopoverOpenChange(event) {
7079
- this.isMorePopoverOpen.set(event);
7080
- }
7081
7237
  async showItemDetail(item, index) {
7082
- const columnData = this.rowData[this.columnName];
7238
+ const columnData = this.rowData[this.columnName()];
7083
7239
  const id = Array.isArray(columnData) ? columnData[index] : columnData;
7084
7240
  this.selectedItemIndex.set(index);
7085
- this.closeMorePopover();
7086
- if (this.entity && id) {
7241
+ const entityKey = this.entity();
7242
+ if (entityKey && id) {
7087
7243
  await this.entityDetailPopoverService.show(this.host, {
7088
- entity: this.entity,
7244
+ entity: entityKey,
7089
7245
  id: id,
7090
- textField: this.textField,
7091
- valueField: this.valueField,
7246
+ textField: this.textField(),
7247
+ valueField: this.valueField(),
7092
7248
  item,
7093
7249
  });
7094
7250
  }
7095
7251
  }
7096
7252
  handleItemClick(index) {
7097
- const items = this.allItems();
7253
+ const items = this.visibleItems();
7098
7254
  if (index < items.length) {
7099
7255
  const item = items[index];
7100
7256
  this.showItemDetail(item, index);
7101
7257
  }
7102
7258
  }
7103
- //#endregion
7104
- //#region ---- Private Methods ----
7105
- openMorePopover() {
7106
- if (this.morePopover() && this.moreButton()) {
7107
- this.morePopover().target = this.moreButton().nativeElement;
7108
- this.morePopover().open();
7109
- this.isMorePopoverOpen.set(true);
7259
+ getItemPath(item) {
7260
+ if (!item) {
7261
+ return [];
7110
7262
  }
7263
+ // If path is available as array, return it
7264
+ if (item.path && Array.isArray(item.path) && item.path.length > 0) {
7265
+ return item.path;
7266
+ }
7267
+ // Fall back to display field if no path
7268
+ const displayValue = get(item, this.displayField());
7269
+ return displayValue ? [String(displayValue)] : [];
7111
7270
  }
7112
- closeMorePopover() {
7113
- if (this.morePopover()) {
7114
- this.morePopover().close();
7115
- this.isMorePopoverOpen.set(false);
7271
+ hasParent(item) {
7272
+ const path = this.getItemPath(item);
7273
+ return path.length > 1;
7274
+ }
7275
+ getItemText(item) {
7276
+ const path = this.getItemPath(item);
7277
+ if (path.length === 0) {
7278
+ return '';
7116
7279
  }
7280
+ // Return the last item in the path (the actual node)
7281
+ return path[path.length - 1];
7117
7282
  }
7118
- extractItem(item) {
7283
+ getItemId(item) {
7284
+ if (!item) {
7285
+ return '';
7286
+ }
7287
+ return String(get(item, this.valueField()) ?? '');
7288
+ }
7289
+ //#endregion
7290
+ //#region ---- Private Methods ----
7291
+ async extractItemWithPath(item) {
7119
7292
  if (isNil(item)) {
7120
7293
  return null;
7121
7294
  }
7295
+ let itemObj;
7122
7296
  if (typeof item === 'object') {
7123
- return item;
7297
+ itemObj = item;
7124
7298
  }
7125
- return {
7126
- [this.valueField]: item,
7127
- [this.textField]: item,
7128
- };
7299
+ else {
7300
+ // If item is just an ID, fetch the full item
7301
+ const byKey = this.entityDef()?.queries.byKey?.execute;
7302
+ if (byKey) {
7303
+ try {
7304
+ itemObj = await byKey(item);
7305
+ }
7306
+ catch (error) {
7307
+ console.error('Error fetching item:', error);
7308
+ return null;
7309
+ }
7310
+ }
7311
+ else {
7312
+ itemObj = {
7313
+ [this.valueField()]: item,
7314
+ [this.textField()]: item,
7315
+ };
7316
+ }
7317
+ }
7318
+ // If item already has a path array, return it as is
7319
+ if (itemObj.path && Array.isArray(itemObj.path) && itemObj.path.length > 0) {
7320
+ return itemObj;
7321
+ }
7322
+ // Calculate path for the item
7323
+ return await this.calculateItemPath(itemObj);
7129
7324
  }
7130
- getDisplayText(item) {
7131
- if (!item) {
7132
- return '';
7325
+ /**
7326
+ * Calculate the full path from root to the item.
7327
+ * Returns an array of strings like ["C", "B"] for item B under parent C.
7328
+ */
7329
+ async calculateItemPath(item) {
7330
+ if (!item || !this.entityDef()) {
7331
+ return item;
7332
+ }
7333
+ // If item already has a path array, return it as is
7334
+ if (item.path && Array.isArray(item.path) && item.path.length > 0) {
7335
+ return item;
7336
+ }
7337
+ const parentKey = this.entityDef()?.parentKey;
7338
+ if (!parentKey) {
7339
+ // No parent key means flat structure, return item with just its title as path array
7340
+ const title = get(item, this.displayField()) ?? '';
7341
+ return { ...item, path: title ? [title] : [] };
7133
7342
  }
7134
- return item?.[this.textField] ?? String(item);
7343
+ const valueField = this.valueField();
7344
+ const textField = this.displayField();
7345
+ const byKey = this.entityDef()?.queries.byKey?.execute;
7346
+ if (!byKey) {
7347
+ return item;
7348
+ }
7349
+ const path = [];
7350
+ let currentItem = item;
7351
+ const visitedIds = new Set(); // Prevent infinite loops
7352
+ // Build path by traversing up the parent chain
7353
+ while (currentItem) {
7354
+ const currentId = String(get(currentItem, valueField) ?? '');
7355
+ if (!currentId || visitedIds.has(currentId)) {
7356
+ break; // Prevent infinite loops
7357
+ }
7358
+ visitedIds.add(currentId);
7359
+ const title = String(get(currentItem, textField) ?? '');
7360
+ if (title) {
7361
+ path.unshift(title); // Add to beginning to maintain hierarchy order
7362
+ }
7363
+ // Get parent ID from current item
7364
+ const parentId = get(currentItem, parentKey);
7365
+ if (!parentId || parentId === 'all' || parentId === currentId) {
7366
+ break; // Reached root or invalid parent
7367
+ }
7368
+ try {
7369
+ // Fetch parent item
7370
+ const parentItem = await byKey(parentId);
7371
+ if (!parentItem) {
7372
+ break; // Parent not found, stop traversal
7373
+ }
7374
+ currentItem = parentItem;
7375
+ }
7376
+ catch (error) {
7377
+ console.error('Error fetching parent item:', error);
7378
+ break;
7379
+ }
7380
+ }
7381
+ // Return item with path array, or just the item title if no path
7382
+ const pathArray = path.length > 0 ? path : get(item, textField) ? [String(get(item, textField))] : [];
7383
+ return { ...item, path: pathArray };
7135
7384
  }
7136
7385
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryWidgetColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
7137
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityCategoryWidgetColumnComponent, isStandalone: true, selector: "axp-entity-category-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, viewQueries: [{ propertyName: "moreButton", first: true, predicate: ["moreButton"], descendants: true, isSignal: true }, { propertyName: "morePopover", first: true, predicate: ["morePopover"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
7138
- <div class="ax-flex ax-items-center ax-gap-1 ax-flex-wrap">
7139
- @for (item of visibleItems(); track $index) {
7140
- <ax-badge
7141
- class="ax-p-0.5 ax-cursor-pointer"
7142
- [text]="getDisplayText(item)"
7143
- (click)="handleItemClick($index)"
7144
- ></ax-badge>
7145
- }
7146
- @if (hasMoreItems()) {
7147
- <span class="ax-cursor-pointer ax-px-1" (click)="showMoreItems()" #moreButton>
7148
- <i class="fas fa-ellipsis-h"></i>
7149
- </span>
7150
- <ax-popover #morePopover [openOn]="'manual'" (openChange)="onMorePopoverOpenChange($event)">
7151
- <div class="ax-p-2 ax-flex ax-flex-col ax-gap-1">
7152
- @for (item of remainingItems(); track $index) {
7153
- <ax-badge
7154
- class="ax-p-0.5 ax-cursor-pointer"
7155
- [text]="getDisplayText(item)"
7156
- (click)="handleItemClick(visibleItems().length + $index)"
7157
- ></ax-badge>
7158
- }
7159
- </div>
7160
- </ax-popover>
7386
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPEntityCategoryWidgetColumnComponent, isStandalone: true, selector: "axp-entity-category-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData", rawValueInput: ["rawValue", "rawValueInput"] }, host: { classAttribute: "ax-w-full" }, usesInheritance: true, ngImport: i0, template: `
7387
+ <div class="ax-flex ax-flex-col ax-gap-1.5">
7388
+ @for (item of visibleItems(); track getItemId(item)) {
7389
+ <div class=" ax-cursor-pointer" (click)="handleItemClick($index)">
7390
+ @if (hasParent(item)) {
7391
+ <ax-badge [color]="'primary'" [look]="'twotone'" class="ax-p-0.5" [text]="getItemText(item)">
7392
+ <ax-prefix>
7393
+ <i class="fas fa-ellipsis-h ax-text-neutral-400 ax-text-xs ax-ps-1"></i>
7394
+ <i class="fas fa-chevron-right ax-text-neutral-400 ax-text-xs ax-px-1"></i>
7395
+ </ax-prefix>
7396
+ </ax-badge>
7397
+ } @else {
7398
+ <ax-badge [color]="'primary'" [look]="'twotone'" class="ax-p-0.5" [text]="getItemText(item)"> </ax-badge>
7399
+ }
7400
+ </div>
7161
7401
  }
7162
7402
  </div>
7163
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2$2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7403
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2$2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7164
7404
  }
7165
7405
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPEntityCategoryWidgetColumnComponent, decorators: [{
7166
7406
  type: Component,
7167
7407
  args: [{
7168
7408
  selector: 'axp-entity-category-widget-column',
7409
+ host: {
7410
+ class: 'ax-w-full',
7411
+ },
7169
7412
  template: `
7170
- <div class="ax-flex ax-items-center ax-gap-1 ax-flex-wrap">
7171
- @for (item of visibleItems(); track $index) {
7172
- <ax-badge
7173
- class="ax-p-0.5 ax-cursor-pointer"
7174
- [text]="getDisplayText(item)"
7175
- (click)="handleItemClick($index)"
7176
- ></ax-badge>
7177
- }
7178
- @if (hasMoreItems()) {
7179
- <span class="ax-cursor-pointer ax-px-1" (click)="showMoreItems()" #moreButton>
7180
- <i class="fas fa-ellipsis-h"></i>
7181
- </span>
7182
- <ax-popover #morePopover [openOn]="'manual'" (openChange)="onMorePopoverOpenChange($event)">
7183
- <div class="ax-p-2 ax-flex ax-flex-col ax-gap-1">
7184
- @for (item of remainingItems(); track $index) {
7185
- <ax-badge
7186
- class="ax-p-0.5 ax-cursor-pointer"
7187
- [text]="getDisplayText(item)"
7188
- (click)="handleItemClick(visibleItems().length + $index)"
7189
- ></ax-badge>
7190
- }
7191
- </div>
7192
- </ax-popover>
7413
+ <div class="ax-flex ax-flex-col ax-gap-1.5">
7414
+ @for (item of visibleItems(); track getItemId(item)) {
7415
+ <div class=" ax-cursor-pointer" (click)="handleItemClick($index)">
7416
+ @if (hasParent(item)) {
7417
+ <ax-badge [color]="'primary'" [look]="'twotone'" class="ax-p-0.5" [text]="getItemText(item)">
7418
+ <ax-prefix>
7419
+ <i class="fas fa-ellipsis-h ax-text-neutral-400 ax-text-xs ax-ps-1"></i>
7420
+ <i class="fas fa-chevron-right ax-text-neutral-400 ax-text-xs ax-px-1"></i>
7421
+ </ax-prefix>
7422
+ </ax-badge>
7423
+ } @else {
7424
+ <ax-badge [color]="'primary'" [look]="'twotone'" class="ax-p-0.5" [text]="getItemText(item)"> </ax-badge>
7425
+ }
7426
+ </div>
7193
7427
  }
7194
7428
  </div>
7195
7429
  `,
7196
7430
  changeDetection: ChangeDetectionStrategy.OnPush,
7197
- imports: [CommonModule, AXBadgeModule, AXButtonModule, AXPopoverModule],
7431
+ imports: [CommonModule, AXBadgeModule, AXDecoratorModule],
7198
7432
  inputs: ['rawValue', 'rowData'],
7199
7433
  }]
7200
- }], propDecorators: { moreButton: [{ type: i0.ViewChild, args: ['moreButton', { isSignal: true }] }], morePopover: [{ type: i0.ViewChild, args: ['morePopover', { isSignal: true }] }] } });
7434
+ }], propDecorators: { rawValueInput: [{
7435
+ type: Input,
7436
+ args: ['rawValue']
7437
+ }] } });
7201
7438
 
7202
7439
  var entityCategoryWidgetColumn_component = /*#__PURE__*/Object.freeze({
7203
7440
  __proto__: null,