@acorex-platform/framework-client 0.0.60 → 0.0.61
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 { InjectionToken, signal, computed, effect, untracked, Injectable, inject, ElementRef, DestroyRef, EventEmitter, Injector, ChangeDetectorRef, ViewChild, Input, Output, ChangeDetectionStrategy, Component, input, output, ViewContainerRef, Directive, NgModule } from '@angular/core';
|
|
2
|
+
import { InjectionToken, signal, computed, effect, untracked, Injectable, inject, ElementRef, DestroyRef, PLATFORM_ID, EventEmitter, Injector, ChangeDetectorRef, ViewChild, Input, Output, ChangeDetectionStrategy, Component, input, output, ViewContainerRef, Directive, NgModule } from '@angular/core';
|
|
3
3
|
import { AXPContextStore, AXPDeviceService, AXPExpressionEvaluatorService, AXPDebugService, FORM_DIRTY_TRACE_NS, OVERLAY_WIDGET_SETTLE_TRACE_NS } from '@acorex-platform/framework-client/core';
|
|
4
4
|
import { AXPPageStatus, AXPWidgetStatus, AXP_WIDGET_TOKEN, AXP_WIDGET_COLUMN_TOKEN, layoutProfileMediumFromRenderMode, resolveLayoutProfile, createStringProperty, createBooleanProperty, createSelectProperty, createNumberProperty, cloneProperty } from '@acorex-platform/framework-shared/widget-core';
|
|
5
5
|
import { cloneDeep, set, get, isEqual, isNil, isUndefined, isObjectLike, merge, sum, isEmpty, isString } from 'lodash-es';
|
|
@@ -15,7 +15,7 @@ import * as i2 from '@acorex/core/translation';
|
|
|
15
15
|
import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
|
|
16
16
|
import { PortalModule } from '@angular/cdk/portal';
|
|
17
17
|
import * as i1 from '@angular/common';
|
|
18
|
-
import { CommonModule, NgComponentOutlet } from '@angular/common';
|
|
18
|
+
import { isPlatformBrowser, CommonModule, NgComponentOutlet } from '@angular/common';
|
|
19
19
|
import { AXDataTableColumnComponent, AXBaseDataTable } from '@acorex/components/data-table';
|
|
20
20
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
21
21
|
import { AXUnsubscriber } from '@acorex/core/utils';
|
|
@@ -2123,6 +2123,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2123
2123
|
}]
|
|
2124
2124
|
}] });
|
|
2125
2125
|
|
|
2126
|
+
const AXP_WIDGET_COLUMN_AUTO_FIT = new InjectionToken('AXP_WIDGET_COLUMN_AUTO_FIT');
|
|
2127
|
+
|
|
2126
2128
|
class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
2127
2129
|
constructor() {
|
|
2128
2130
|
super(...arguments);
|
|
@@ -2131,6 +2133,7 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2131
2133
|
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
2132
2134
|
this.translation = inject(AXTranslationService);
|
|
2133
2135
|
this.destroyRef = inject(DestroyRef);
|
|
2136
|
+
this.platformId = inject(PLATFORM_ID);
|
|
2134
2137
|
/** Original band title key; caption becomes resolved text and must not be re-read for i18n. */
|
|
2135
2138
|
this.bandCaptionI18nKey = null;
|
|
2136
2139
|
this.bandLocaleWatchStarted = false;
|
|
@@ -2143,6 +2146,21 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2143
2146
|
this.pendingEvaluations = new Set();
|
|
2144
2147
|
this.changeDetectionScheduled = false;
|
|
2145
2148
|
this.MAX_CACHE_SIZE = 1000; // Limit cache size to prevent memory leaks
|
|
2149
|
+
/** Column was configured with `width: 'auto'` and should follow cell content. */
|
|
2150
|
+
this.autoWidthColumn = false;
|
|
2151
|
+
/** Further content passes are ignored after the directive-rendered cell has been measured. */
|
|
2152
|
+
this.contentAutoFitSettled = false;
|
|
2153
|
+
this.contentAutoFitShouldSettle = false;
|
|
2154
|
+
this.contentAutoFitAttempts = 0;
|
|
2155
|
+
this.contentAutoFitTimer = null;
|
|
2156
|
+
/** Matches the cap `ax-data-table` uses for its own auto-width pass. */
|
|
2157
|
+
this.contentAutoFitMaxWidth = 500;
|
|
2158
|
+
this.stopContentAutoFit = this.destroyRef.onDestroy(() => {
|
|
2159
|
+
if (this.contentAutoFitTimer != null) {
|
|
2160
|
+
clearTimeout(this.contentAutoFitTimer);
|
|
2161
|
+
this.contentAutoFitTimer = null;
|
|
2162
|
+
}
|
|
2163
|
+
});
|
|
2146
2164
|
/** When true, header click cycles sort (handled by parent; synced with list sort state). */
|
|
2147
2165
|
this.sortEnabled = false;
|
|
2148
2166
|
this.sortToggle = new EventEmitter();
|
|
@@ -2304,8 +2322,10 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2304
2322
|
: (this.mergedOptions().width ?? '200px');
|
|
2305
2323
|
this.allowResizing = this.mergedOptions().allowResizing !== false;
|
|
2306
2324
|
this.allowSorting = this.sortEnabled;
|
|
2325
|
+
this.syncAutoWidthIntent();
|
|
2307
2326
|
this.cdr.detectChanges();
|
|
2308
2327
|
this.fixed = this.columnFixed;
|
|
2328
|
+
this.scheduleContentAutoFit();
|
|
2309
2329
|
}
|
|
2310
2330
|
ngAfterContentInit() {
|
|
2311
2331
|
if (!this.isBand) {
|
|
@@ -2325,6 +2345,7 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2325
2345
|
if (this.customWidth) {
|
|
2326
2346
|
this.width = this.customWidth;
|
|
2327
2347
|
}
|
|
2348
|
+
this.syncAutoWidthIntent();
|
|
2328
2349
|
if (this.node) {
|
|
2329
2350
|
this.allowResizing = this.mergedOptions().allowResizing !== false;
|
|
2330
2351
|
}
|
|
@@ -2437,6 +2458,7 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2437
2458
|
requestAnimationFrame(() => {
|
|
2438
2459
|
this.cdr.detectChanges();
|
|
2439
2460
|
this.changeDetectionScheduled = false;
|
|
2461
|
+
this.scheduleContentAutoFit();
|
|
2440
2462
|
});
|
|
2441
2463
|
}
|
|
2442
2464
|
/**
|
|
@@ -2451,6 +2473,52 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2451
2473
|
}
|
|
2452
2474
|
}
|
|
2453
2475
|
//#endregion
|
|
2476
|
+
/**
|
|
2477
|
+
* Re-measures this column after cell widgets exist.
|
|
2478
|
+
* The table's own pass runs once, about 100ms after rows arrive, which is before
|
|
2479
|
+
* `ngComponentOutlet` / `axp-widget-renderer` have painted.
|
|
2480
|
+
*/
|
|
2481
|
+
scheduleContentAutoFit(request) {
|
|
2482
|
+
if (!isPlatformBrowser(this.platformId) || !this.autoWidthColumn || this.contentAutoFitSettled) {
|
|
2483
|
+
return;
|
|
2484
|
+
}
|
|
2485
|
+
this.contentAutoFitShouldSettle = this.contentAutoFitShouldSettle || request?.settle === true;
|
|
2486
|
+
if (this.contentAutoFitTimer != null) {
|
|
2487
|
+
clearTimeout(this.contentAutoFitTimer);
|
|
2488
|
+
}
|
|
2489
|
+
this.contentAutoFitTimer = setTimeout(() => {
|
|
2490
|
+
this.contentAutoFitTimer = null;
|
|
2491
|
+
if (!this.autoWidthColumn || this.contentAutoFitSettled) {
|
|
2492
|
+
return;
|
|
2493
|
+
}
|
|
2494
|
+
if (this.pendingEvaluations.size > 0 && this.contentAutoFitAttempts < 20) {
|
|
2495
|
+
this.contentAutoFitAttempts += 1;
|
|
2496
|
+
this.scheduleContentAutoFit({ settle: this.contentAutoFitShouldSettle });
|
|
2497
|
+
return;
|
|
2498
|
+
}
|
|
2499
|
+
this.contentAutoFitAttempts = 0;
|
|
2500
|
+
if (this.contentAutoFitShouldSettle) {
|
|
2501
|
+
this.contentAutoFitSettled = true;
|
|
2502
|
+
}
|
|
2503
|
+
this.contentAutoFitShouldSettle = false;
|
|
2504
|
+
this.grid.autoFitColumnByName(this.name, { maxWidth: this.contentAutoFitMaxWidth });
|
|
2505
|
+
}, 100);
|
|
2506
|
+
}
|
|
2507
|
+
syncAutoWidthIntent() {
|
|
2508
|
+
if (!this.node || this.isBand) {
|
|
2509
|
+
this.autoWidthColumn = false;
|
|
2510
|
+
}
|
|
2511
|
+
else {
|
|
2512
|
+
const configured = this.customWidth || this.mergedOptions()?.width;
|
|
2513
|
+
this.autoWidthColumn = configured === 'auto' || this.width === 'auto';
|
|
2514
|
+
}
|
|
2515
|
+
if (!this.autoWidthColumn && this.contentAutoFitTimer != null) {
|
|
2516
|
+
clearTimeout(this.contentAutoFitTimer);
|
|
2517
|
+
this.contentAutoFitTimer = null;
|
|
2518
|
+
this.contentAutoFitShouldSettle = false;
|
|
2519
|
+
this.contentAutoFitAttempts = 0;
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2454
2522
|
requireNode() {
|
|
2455
2523
|
if (!this.node) {
|
|
2456
2524
|
throw new Error('axp-widget-column-renderer: node is required for leaf columns');
|
|
@@ -2485,6 +2553,10 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2485
2553
|
provide: AXP_WIDGET_COLUMN_TOKEN,
|
|
2486
2554
|
useValue: tokenValue,
|
|
2487
2555
|
},
|
|
2556
|
+
{
|
|
2557
|
+
provide: AXP_WIDGET_COLUMN_AUTO_FIT,
|
|
2558
|
+
useValue: this,
|
|
2559
|
+
},
|
|
2488
2560
|
],
|
|
2489
2561
|
});
|
|
2490
2562
|
this.evictCacheIfNeeded();
|
|
@@ -2520,6 +2592,10 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2520
2592
|
provide: AXP_WIDGET_COLUMN_TOKEN,
|
|
2521
2593
|
useValue: tokenValue,
|
|
2522
2594
|
},
|
|
2595
|
+
{
|
|
2596
|
+
provide: AXP_WIDGET_COLUMN_AUTO_FIT,
|
|
2597
|
+
useValue: this,
|
|
2598
|
+
},
|
|
2523
2599
|
],
|
|
2524
2600
|
});
|
|
2525
2601
|
// Replace cached injector to force component recreation on next render
|
|
@@ -2548,6 +2624,10 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2548
2624
|
provide: AXP_WIDGET_COLUMN_TOKEN,
|
|
2549
2625
|
useValue: tokenValue,
|
|
2550
2626
|
},
|
|
2627
|
+
{
|
|
2628
|
+
provide: AXP_WIDGET_COLUMN_AUTO_FIT,
|
|
2629
|
+
useValue: this,
|
|
2630
|
+
},
|
|
2551
2631
|
],
|
|
2552
2632
|
});
|
|
2553
2633
|
// Cache the initial injector
|
|
@@ -2563,6 +2643,10 @@ class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
|
|
|
2563
2643
|
provide: AXDataTableColumnComponent,
|
|
2564
2644
|
useExisting: AXPWidgetColumnRendererComponent,
|
|
2565
2645
|
},
|
|
2646
|
+
{
|
|
2647
|
+
provide: AXP_WIDGET_COLUMN_AUTO_FIT,
|
|
2648
|
+
useExisting: AXPWidgetColumnRendererComponent,
|
|
2649
|
+
},
|
|
2566
2650
|
], 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: `
|
|
2567
2651
|
<ng-template #header>
|
|
2568
2652
|
<div
|
|
@@ -2807,6 +2891,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2807
2891
|
provide: AXDataTableColumnComponent,
|
|
2808
2892
|
useExisting: AXPWidgetColumnRendererComponent,
|
|
2809
2893
|
},
|
|
2894
|
+
{
|
|
2895
|
+
provide: AXP_WIDGET_COLUMN_AUTO_FIT,
|
|
2896
|
+
useExisting: AXPWidgetColumnRendererComponent,
|
|
2897
|
+
},
|
|
2810
2898
|
], changeDetection: ChangeDetectionStrategy.OnPush, inputs: ['caption'], standalone: false, styles: ["@layer properties;.axp-widget-column-header--sortable{position:relative;width:100%;min-width:0px;cursor:pointer}.axp-widget-column-header--sortable:hover .axp-widget-column-header__sort,.axp-widget-column-header--sortable:focus-within .axp-widget-column-header__sort,.axp-widget-column-header--sortable.axp-widget-column-header--sort-active .axp-widget-column-header__sort{opacity:1}.axp-widget-column-header--sortable:hover .axp-widget-column-header__caption,.axp-widget-column-header--sortable:focus-within .axp-widget-column-header__caption,.axp-widget-column-header--sortable.axp-widget-column-header--sort-active .axp-widget-column-header__caption{padding-inline-end:calc(var(--spacing, .25rem) * 5)}.axp-widget-column-header--sortable.axp-widget-column-header--sort-at-start:hover .axp-widget-column-header__caption,.axp-widget-column-header--sortable.axp-widget-column-header--sort-at-start:focus-within .axp-widget-column-header__caption,.axp-widget-column-header--sortable.axp-widget-column-header--sort-at-start.axp-widget-column-header--sort-active .axp-widget-column-header__caption{padding-inline-start:calc(var(--spacing, .25rem) * 5);padding-inline-end:0px}.axp-widget-column-header__caption{display:block;width:100%;min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.axp-widget-column-header__sort{position:absolute;inset-block:0;inset-inline-end:0;z-index:1;display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * .5);opacity:0;transition:opacity .15s ease}.axp-widget-column-header--sort-at-start .axp-widget-column-header__sort{inset-inline-start:0;inset-inline-end:auto}.axp-widget-column-header__sort i{display:block;--tw-leading: 1;line-height:1;font-size:.625rem}.axp-widget-column-header__sort-priority{--tw-leading: 1;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,:host-context(.ax-data-table-head-cell) .axp-widget-column-header--sort-active .axp-widget-column-header__sort{opacity:1}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
2811
2899
|
}], propDecorators: { customExpandIcon: [{
|
|
2812
2900
|
type: Input
|
|
@@ -3246,6 +3334,7 @@ class AXPWidgetRendererDirective {
|
|
|
3246
3334
|
this.widgetService = inject(AXPWidgetRegistryService);
|
|
3247
3335
|
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
3248
3336
|
this.viewContainerRef = inject(ViewContainerRef);
|
|
3337
|
+
this.columnAutoFit = inject(AXP_WIDGET_COLUMN_AUTO_FIT, { optional: true });
|
|
3249
3338
|
this.isLoading = signal(false, /* @ts-ignore */
|
|
3250
3339
|
...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
|
|
3251
3340
|
this.isVisible = signal(true, /* @ts-ignore */
|
|
@@ -3900,6 +3989,7 @@ class AXPWidgetRendererDirective {
|
|
|
3900
3989
|
const loadEvent = { sender: this, widget: this.instance };
|
|
3901
3990
|
this.onLoadEvent.next(loadEvent);
|
|
3902
3991
|
this.onLoad.emit(loadEvent);
|
|
3992
|
+
this.columnAutoFit?.scheduleContentAutoFit({ settle: true });
|
|
3903
3993
|
}
|
|
3904
3994
|
catch (error) {
|
|
3905
3995
|
// console.error('Error loading component:', error);
|