@acorex/platform 20.8.18 → 20.8.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { computed, signal, Injectable, InjectionToken, inject, ElementRef, effect, untracked, Injector, ChangeDetectorRef, ViewChild, Input, ChangeDetectionStrategy, Component, EventEmitter, Output, input, output, ViewContainerRef, Directive, Optional, Inject, NgModule } from '@angular/core';
2
+ import { computed, signal, Injectable, InjectionToken, inject, ElementRef, effect, untracked, EventEmitter, Injector, ChangeDetectorRef, ViewChild, Input, Output, ChangeDetectionStrategy, Component, input, output, ViewContainerRef, Directive, Optional, Inject, NgModule } from '@angular/core';
3
3
  import { convertArrayToDataSource, AXDataSource } from '@acorex/cdk/common';
4
4
  import { setSmart, AXPDataSourceDefinitionProviderService, extractValue, AXPExpressionEvaluatorService, getSmart } from '@acorex/platform/core';
5
5
  import { cloneDeep, isEqual, has, get, set, merge, isNil, isUndefined, isObjectLike, sum, isEmpty, isString } from 'lodash-es';
@@ -1229,6 +1229,9 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
1229
1229
  this.pendingEvaluations = new Set();
1230
1230
  this.changeDetectionScheduled = false;
1231
1231
  this.MAX_CACHE_SIZE = 1000; // Limit cache size to prevent memory leaks
1232
+ /** When true, header click cycles sort (handled by parent; synced with list sort state). */
1233
+ this.sortEnabled = false;
1234
+ this.sortToggle = new EventEmitter();
1232
1235
  this.injector = inject(Injector);
1233
1236
  this.cdr = inject(ChangeDetectorRef);
1234
1237
  }
@@ -1276,6 +1279,23 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
1276
1279
  getHeaderTextAlign() {
1277
1280
  return this.resolveAlignForSide('header');
1278
1281
  }
1282
+ getHeaderJustifyContent() {
1283
+ const align = this.getHeaderTextAlign();
1284
+ if (align === 'center') {
1285
+ return 'center';
1286
+ }
1287
+ if (align === 'end') {
1288
+ return 'flex-end';
1289
+ }
1290
+ return 'flex-start';
1291
+ }
1292
+ onHeaderClick(event) {
1293
+ if (!this.sortEnabled) {
1294
+ return;
1295
+ }
1296
+ event.stopPropagation();
1297
+ this.sortToggle.emit(event);
1298
+ }
1279
1299
  /**
1280
1300
  * When true, the cell body uses flex so `justify-content` can place content on the main axis.
1281
1301
  */
@@ -1354,8 +1374,14 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
1354
1374
  });
1355
1375
  this.width = this.mergedOptions().width === 'auto' ? 'auto' : this.customWidth ? this.customWidth : (this.mergedOptions().width ?? '200px');
1356
1376
  this.allowResizing = this.mergedOptions().allowResizing || true;
1377
+ this.allowSorting = this.sortEnabled;
1357
1378
  this.cdr.detectChanges();
1358
1379
  }
1380
+ ngOnChanges() {
1381
+ this.allowSorting = this.sortEnabled;
1382
+ this.sortOrder = this.headerSortDirection;
1383
+ this.sortIndex = this.headerSortPriority;
1384
+ }
1359
1385
  //#region ---- Performance Optimization Methods ----
1360
1386
  /**
1361
1387
  * Check if options contain any expressions that need evaluation
@@ -1515,12 +1541,34 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
1515
1541
  return rowInjector;
1516
1542
  }
1517
1543
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPWidgetColumnRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1518
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: AXPWidgetColumnRendererComponent, isStandalone: false, selector: "axp-widget-column-renderer", inputs: { caption: "caption", customExpandIcon: "customExpandIcon", customCollapseIcon: "customCollapseIcon", customWidth: "customWidth", node: "node", footerTemplate: "footerTemplate", expandHandler: "expandHandler", cellTemplate: "cellTemplate", headerTemplate: "headerTemplate" }, providers: [
1544
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: AXPWidgetColumnRendererComponent, isStandalone: false, selector: "axp-widget-column-renderer", inputs: { caption: "caption", customExpandIcon: "customExpandIcon", customCollapseIcon: "customCollapseIcon", customWidth: "customWidth", node: "node", footerTemplate: "footerTemplate", expandHandler: "expandHandler", sortEnabled: "sortEnabled", headerSortDirection: "headerSortDirection", headerSortPriority: "headerSortPriority", cellTemplate: "cellTemplate", headerTemplate: "headerTemplate" }, outputs: { sortToggle: "sortToggle" }, providers: [
1519
1545
  AXPWidgetCoreService,
1520
1546
  { provide: AXDataTableColumnComponent, useExisting: AXPWidgetColumnRendererComponent },
1521
- ], viewQueries: [{ propertyName: "_contentFooterTemplate", first: true, predicate: ["footer"], descendants: true }, { propertyName: "_contentCellTemplate", first: true, predicate: ["cell"], descendants: true }, { propertyName: "_contentHeaderTemplate", first: true, predicate: ["header"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
1547
+ ], viewQueries: [{ propertyName: "_contentFooterTemplate", first: true, predicate: ["footer"], descendants: true }, { propertyName: "_contentCellTemplate", first: true, predicate: ["cell"], descendants: true }, { propertyName: "_contentHeaderTemplate", first: true, predicate: ["header"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
1522
1548
  <ng-template #header>
1523
- <div class="ax-w-full" [style.text-align]="getHeaderTextAlign()">{{ caption | translate | async }}</div>
1549
+ <div
1550
+ class="axp-widget-column-header ax-w-full ax-flex ax-items-center ax-gap-1 ax-select-none"
1551
+ [class.axp-widget-column-header--sortable]="sortEnabled"
1552
+ [style.justify-content]="getHeaderJustifyContent()"
1553
+ (click)="onHeaderClick($event)"
1554
+ >
1555
+ <span class="axp-widget-column-header__caption ax-truncate">{{ caption | translate | async }}</span>
1556
+ @if (sortEnabled) {
1557
+ <span class="axp-widget-column-header__sort ax-flex ax-items-center ax-gap-0.5 ax-shrink-0">
1558
+ @if (headerSortPriority !== undefined && headerSortPriority > 1) {
1559
+ <span class="axp-widget-column-header__sort-priority ax-text-xs ax-opacity-70">{{ headerSortPriority }}</span>
1560
+ }
1561
+ <i
1562
+ class="fa-solid fa-arrow-up-long ax-text-neutral-400"
1563
+ [class.ax-text-primary]="headerSortDirection === 'asc'"
1564
+ ></i>
1565
+ <i
1566
+ class="fa-solid fa-arrow-down-long ax-text-neutral-400"
1567
+ [class.ax-text-primary]="headerSortDirection === 'desc'"
1568
+ ></i>
1569
+ </span>
1570
+ }
1571
+ </div>
1524
1572
  </ng-template>
1525
1573
  <ng-template #cell let-row>
1526
1574
  <div
@@ -1557,15 +1605,35 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
1557
1605
  </div>
1558
1606
  </ng-template>
1559
1607
  <ng-template #footer></ng-template>
1560
- `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1608
+ `, isInline: true, styles: [".axp-widget-column-header--sortable{cursor:pointer}.axp-widget-column-header__caption{min-width:0}.axp-widget-column-header__sort{opacity:0;transition:opacity .15s ease}.axp-widget-column-header--sortable:hover .axp-widget-column-header__sort,.axp-widget-column-header--sortable:focus-within .axp-widget-column-header__sort{opacity:1}.axp-widget-column-header__sort-priority{line-height:1}:host-context(.ax-data-table-head-cell.ax-interactive:hover) .axp-widget-column-header__sort,:host-context(.ax-data-table-head-cell.ax-interactive:focus-within) .axp-widget-column-header__sort{opacity:1}\n"], dependencies: [{ kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1561
1609
  }
1562
1610
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPWidgetColumnRendererComponent, decorators: [{
1563
1611
  type: Component,
1564
- args: [{
1565
- selector: 'axp-widget-column-renderer',
1566
- template: `
1612
+ args: [{ selector: 'axp-widget-column-renderer', template: `
1567
1613
  <ng-template #header>
1568
- <div class="ax-w-full" [style.text-align]="getHeaderTextAlign()">{{ caption | translate | async }}</div>
1614
+ <div
1615
+ class="axp-widget-column-header ax-w-full ax-flex ax-items-center ax-gap-1 ax-select-none"
1616
+ [class.axp-widget-column-header--sortable]="sortEnabled"
1617
+ [style.justify-content]="getHeaderJustifyContent()"
1618
+ (click)="onHeaderClick($event)"
1619
+ >
1620
+ <span class="axp-widget-column-header__caption ax-truncate">{{ caption | translate | async }}</span>
1621
+ @if (sortEnabled) {
1622
+ <span class="axp-widget-column-header__sort ax-flex ax-items-center ax-gap-0.5 ax-shrink-0">
1623
+ @if (headerSortPriority !== undefined && headerSortPriority > 1) {
1624
+ <span class="axp-widget-column-header__sort-priority ax-text-xs ax-opacity-70">{{ headerSortPriority }}</span>
1625
+ }
1626
+ <i
1627
+ class="fa-solid fa-arrow-up-long ax-text-neutral-400"
1628
+ [class.ax-text-primary]="headerSortDirection === 'asc'"
1629
+ ></i>
1630
+ <i
1631
+ class="fa-solid fa-arrow-down-long ax-text-neutral-400"
1632
+ [class.ax-text-primary]="headerSortDirection === 'desc'"
1633
+ ></i>
1634
+ </span>
1635
+ }
1636
+ </div>
1569
1637
  </ng-template>
1570
1638
  <ng-template #cell let-row>
1571
1639
  <div
@@ -1602,15 +1670,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
1602
1670
  </div>
1603
1671
  </ng-template>
1604
1672
  <ng-template #footer></ng-template>
1605
- `,
1606
- providers: [
1673
+ `, providers: [
1607
1674
  AXPWidgetCoreService,
1608
1675
  { provide: AXDataTableColumnComponent, useExisting: AXPWidgetColumnRendererComponent },
1609
- ],
1610
- changeDetection: ChangeDetectionStrategy.OnPush,
1611
- inputs: ['caption'],
1612
- standalone: false,
1613
- }]
1676
+ ], changeDetection: ChangeDetectionStrategy.OnPush, inputs: ['caption'], standalone: false, styles: [".axp-widget-column-header--sortable{cursor:pointer}.axp-widget-column-header__caption{min-width:0}.axp-widget-column-header__sort{opacity:0;transition:opacity .15s ease}.axp-widget-column-header--sortable:hover .axp-widget-column-header__sort,.axp-widget-column-header--sortable:focus-within .axp-widget-column-header__sort{opacity:1}.axp-widget-column-header__sort-priority{line-height:1}:host-context(.ax-data-table-head-cell.ax-interactive:hover) .axp-widget-column-header__sort,:host-context(.ax-data-table-head-cell.ax-interactive:focus-within) .axp-widget-column-header__sort{opacity:1}\n"] }]
1614
1677
  }], propDecorators: { customExpandIcon: [{
1615
1678
  type: Input
1616
1679
  }], customCollapseIcon: [{
@@ -1627,6 +1690,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
1627
1690
  args: ['footer']
1628
1691
  }], expandHandler: [{
1629
1692
  type: Input
1693
+ }], sortEnabled: [{
1694
+ type: Input
1695
+ }], headerSortDirection: [{
1696
+ type: Input
1697
+ }], headerSortPriority: [{
1698
+ type: Input
1699
+ }], sortToggle: [{
1700
+ type: Output
1630
1701
  }], cellTemplate: [{
1631
1702
  type: Input
1632
1703
  }], _contentCellTemplate: [{