@zambon-dev/library 1.5.0 → 1.6.1
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/CHANGELOG.md +44 -1
- package/fesm2022/zambon-dev-library.mjs +131 -62
- package/fesm2022/zambon-dev-library.mjs.map +1 -1
- package/lib/components/data-grid/data-grid.component.d.ts +1 -0
- package/lib/components/data-grid-row/data-grid-row.component.d.ts +1 -1
- package/lib/helpers/display-controls.d.ts +29 -0
- package/lib/helpers/index.d.ts +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -23,6 +23,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
23
23
|
|
|
24
24
|
### ⚠ Breaking Changes / Migration
|
|
25
25
|
|
|
26
|
+
## [1.6.1] - 2026-09-19
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **`lib-data-grid` headings now sit over their own column.** On a grid with many columns each
|
|
31
|
+
heading drifted further from its cells than the last -- up to 263px on a fourteen-column screen --
|
|
32
|
+
and scrolling sideways separated them completely.
|
|
33
|
+
|
|
34
|
+
The body lays the columns out as a CSS grid inside the CDK viewport; the heading row is a flex
|
|
35
|
+
row outside it that copies each column's measured width. Four things pulled the two apart:
|
|
36
|
+
|
|
37
|
+
- The heading cells could **shrink**, so once the columns together were wider than the view every
|
|
38
|
+
heading was compressed a little and the error accumulated across the row.
|
|
39
|
+
- The heading row **did not follow the body sideways**. The rows scroll inside the viewport and
|
|
40
|
+
the headings simply stayed where they were.
|
|
41
|
+
- A column was **measured once and never again**, while the body keeps resizing its
|
|
42
|
+
`minmax(x, min-content)` columns as virtual scrolling brings different content into view.
|
|
43
|
+
- A column measured at **zero** -- a `1fr` column collapsed for want of room -- left its heading
|
|
44
|
+
with no width at all, so it kept its text width and shoved everything to its right along.
|
|
45
|
+
|
|
46
|
+
Headings are now fixed to the measured width, translate with the body's horizontal scroll, track
|
|
47
|
+
every resize, and a heading whose column has collapsed is removed rather than left taking a gap
|
|
48
|
+
the body does not have. Measured in a running application the drift is zero across every column,
|
|
49
|
+
at rest and scrolled.
|
|
50
|
+
|
|
51
|
+
## [1.6.0] - 2026-09-16
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
|
|
55
|
+
- **`DisplayControls`**, which records the form controls that exist only to show a catalog
|
|
56
|
+
selection's label. `lib-catalog-select` works in pairs — `controlName` holds the identifier,
|
|
57
|
+
`displayControlName` holds the text — and it creates the second itself when a screen does not
|
|
58
|
+
declare one, so a form carries controls nobody wrote down. It now marks whichever control it
|
|
59
|
+
drives as its display, and `framework-button-filters` reads that mark to keep those out of what
|
|
60
|
+
it submits.
|
|
61
|
+
|
|
62
|
+
The mark is held in a `WeakSet` keyed by the control instance, not by its name: two forms may
|
|
63
|
+
each have an `employeeName`, and only the one a catalog select drives is a display control.
|
|
64
|
+
Nothing about an application changes — declaring the display control yourself still works, and
|
|
65
|
+
it is marked just the same.
|
|
66
|
+
|
|
26
67
|
## [1.5.0] - 2026-09-09
|
|
27
68
|
|
|
28
69
|
### Added
|
|
@@ -249,7 +290,9 @@ config options and the `getUserProfile()` method still exist but are no longer c
|
|
|
249
290
|
available via [GitHub Releases](https://github.com/RicardoZambon/ZLibraries/releases) and the
|
|
250
291
|
`library-v*` tags.
|
|
251
292
|
|
|
252
|
-
[Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/library-v1.
|
|
293
|
+
[Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/library-v1.6.1...HEAD
|
|
294
|
+
[1.6.1]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.1
|
|
295
|
+
[1.6.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.0
|
|
253
296
|
[1.5.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.5.0
|
|
254
297
|
[1.4.1]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.4.1
|
|
255
298
|
[1.4.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.4.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Component, inject, Injectable, EventEmitter, InjectionToken, Input, Output, KeyValueDiffers, ViewContainerRef, TemplateRef, ElementRef, HostListener, ViewChild, ChangeDetectorRef, ChangeDetectionStrategy, NgZone, Directive, ContentChildren, Pipe, NgModule } from '@angular/core';
|
|
3
|
-
import { Subject, ReplaySubject, take, throwError, tap, map, takeUntil, filter, debounceTime, startWith, pairwise, Observable, forkJoin, switchMap, of, delay, merge } from 'rxjs';
|
|
3
|
+
import { Subject, ReplaySubject, take, throwError, tap, map, takeUntil, filter, debounceTime, startWith, pairwise, Observable, forkJoin, switchMap, of, fromEvent, delay, merge } from 'rxjs';
|
|
4
4
|
import { Overlay, OverlayPositionBuilder } from '@angular/cdk/overlay';
|
|
5
5
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
6
6
|
import * as i1 from '@angular/common';
|
|
@@ -38,6 +38,95 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
|
|
|
38
38
|
args: [{ template: '' }]
|
|
39
39
|
}] });
|
|
40
40
|
|
|
41
|
+
class DateHelpers {
|
|
42
|
+
//#region Public methods
|
|
43
|
+
static diffDays(initialDate, finalDate) {
|
|
44
|
+
const initialDateOnly = new Date(initialDate.getFullYear(), initialDate.getMonth(), initialDate.getDate());
|
|
45
|
+
const finalDateOnly = new Date(finalDate.getFullYear(), finalDate.getMonth(), finalDate.getDate());
|
|
46
|
+
const diff = initialDateOnly.getTime() - finalDateOnly.getTime();
|
|
47
|
+
return Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Tracks the form controls that exist only to show a catalog selection's label.
|
|
53
|
+
*
|
|
54
|
+
* `lib-catalog-select` works in pairs: the control named by `controlName` holds the identifier, and
|
|
55
|
+
* the one named by `displayControlName` holds the text the user reads. The second is created by the
|
|
56
|
+
* component itself when a screen does not declare it, so a form ends up carrying controls nobody
|
|
57
|
+
* wrote down — and a filters form then submits them alongside the real filters.
|
|
58
|
+
*
|
|
59
|
+
* The mark lives in a `WeakSet` keyed by the control instance rather than by its name. That is the
|
|
60
|
+
* only scope that is actually correct: two forms may each have an `employeeName`, and only the one
|
|
61
|
+
* a catalog select drives is a display control. It also keeps nothing alive.
|
|
62
|
+
*/
|
|
63
|
+
class DisplayControls {
|
|
64
|
+
//#region Variables
|
|
65
|
+
static marked = new WeakSet();
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region Public methods
|
|
68
|
+
/**
|
|
69
|
+
* Whether the control exists only to display a catalog selection's label.
|
|
70
|
+
*
|
|
71
|
+
* @param control The control, which may be absent.
|
|
72
|
+
* @returns `true` when a catalog select drives it as its display control.
|
|
73
|
+
*/
|
|
74
|
+
static isDisplayControl(control) {
|
|
75
|
+
return !!control && DisplayControls.marked.has(control);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Marks the control as existing only to display a catalog selection's label.
|
|
79
|
+
*
|
|
80
|
+
* @param control The control, which may be absent.
|
|
81
|
+
*/
|
|
82
|
+
static markAsDisplayControl(control) {
|
|
83
|
+
if (control) {
|
|
84
|
+
DisplayControls.marked.add(control);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
class GuidHelper {
|
|
90
|
+
static generateGUID() {
|
|
91
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
92
|
+
const r = (Math.random() * 16) | 0;
|
|
93
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
94
|
+
return v.toString(16);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
class RouterFormatter {
|
|
100
|
+
//#region ViewChilds, Inputs, Outputs
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region Variables
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region Properties
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region Constructor and Angular life cycle methods
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region Event handlers
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region Public methods
|
|
111
|
+
static getURL(route) {
|
|
112
|
+
let parentRoute = '';
|
|
113
|
+
if (route.parent) {
|
|
114
|
+
parentRoute = this.getURL(route.parent);
|
|
115
|
+
}
|
|
116
|
+
let path = route.routeConfig?.path ?? '';
|
|
117
|
+
route.paramMap.keys
|
|
118
|
+
.forEach(k => {
|
|
119
|
+
path = path.replace(':' + k, k === 'view'
|
|
120
|
+
? ''
|
|
121
|
+
: (route.paramMap.get(k) ?? ''));
|
|
122
|
+
});
|
|
123
|
+
if (!route.parent || (parentRoute !== '' && parentRoute !== '/' && route.routeConfig?.path && path)) {
|
|
124
|
+
parentRoute += '/';
|
|
125
|
+
}
|
|
126
|
+
return parentRoute + path;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
41
130
|
class CatalogService {
|
|
42
131
|
//#region ViewChilds, Inputs, Outputs
|
|
43
132
|
//#endregion
|
|
@@ -193,57 +282,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
|
|
|
193
282
|
type: Injectable
|
|
194
283
|
}], ctorParameters: () => [] });
|
|
195
284
|
|
|
196
|
-
class DateHelpers {
|
|
197
|
-
//#region Public methods
|
|
198
|
-
static diffDays(initialDate, finalDate) {
|
|
199
|
-
const initialDateOnly = new Date(initialDate.getFullYear(), initialDate.getMonth(), initialDate.getDate());
|
|
200
|
-
const finalDateOnly = new Date(finalDate.getFullYear(), finalDate.getMonth(), finalDate.getDate());
|
|
201
|
-
const diff = initialDateOnly.getTime() - finalDateOnly.getTime();
|
|
202
|
-
return Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
class GuidHelper {
|
|
207
|
-
static generateGUID() {
|
|
208
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
209
|
-
const r = (Math.random() * 16) | 0;
|
|
210
|
-
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
211
|
-
return v.toString(16);
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
class RouterFormatter {
|
|
217
|
-
//#region ViewChilds, Inputs, Outputs
|
|
218
|
-
//#endregion
|
|
219
|
-
//#region Variables
|
|
220
|
-
//#endregion
|
|
221
|
-
//#region Properties
|
|
222
|
-
//#endregion
|
|
223
|
-
//#region Constructor and Angular life cycle methods
|
|
224
|
-
//#endregion
|
|
225
|
-
//#region Event handlers
|
|
226
|
-
//#endregion
|
|
227
|
-
//#region Public methods
|
|
228
|
-
static getURL(route) {
|
|
229
|
-
let parentRoute = '';
|
|
230
|
-
if (route.parent) {
|
|
231
|
-
parentRoute = this.getURL(route.parent);
|
|
232
|
-
}
|
|
233
|
-
let path = route.routeConfig?.path ?? '';
|
|
234
|
-
route.paramMap.keys
|
|
235
|
-
.forEach(k => {
|
|
236
|
-
path = path.replace(':' + k, k === 'view'
|
|
237
|
-
? ''
|
|
238
|
-
: (route.paramMap.get(k) ?? ''));
|
|
239
|
-
});
|
|
240
|
-
if (!route.parent || (parentRoute !== '' && parentRoute !== '/' && route.routeConfig?.path && path)) {
|
|
241
|
-
parentRoute += '/';
|
|
242
|
-
}
|
|
243
|
-
return parentRoute + path;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
285
|
class GridConfigsProvider {
|
|
248
286
|
//#region ViewChilds, Inputs, Outputs
|
|
249
287
|
//#endregion
|
|
@@ -1833,6 +1871,10 @@ class CatalogSelectComponent extends BaseComponent {
|
|
|
1833
1871
|
if (!parent.get(name)) {
|
|
1834
1872
|
parent.addControl(name, new FormControl(''));
|
|
1835
1873
|
}
|
|
1874
|
+
// Marked whether this component created it or the screen declared it: what makes a control
|
|
1875
|
+
// a display control is being driven as one, not who wrote it down. A filters form reads the
|
|
1876
|
+
// mark to keep it out of what it submits.
|
|
1877
|
+
DisplayControls.markAsDisplayControl(parent.get(name));
|
|
1836
1878
|
}
|
|
1837
1879
|
});
|
|
1838
1880
|
}
|
|
@@ -2173,7 +2215,7 @@ class DataGridRowComponent extends BaseComponent {
|
|
|
2173
2215
|
dataGridDataset = inject(DataGridDataset);
|
|
2174
2216
|
selected = false;
|
|
2175
2217
|
_rowData;
|
|
2176
|
-
|
|
2218
|
+
hasMeasured = {};
|
|
2177
2219
|
//#endregion
|
|
2178
2220
|
//#region Properties
|
|
2179
2221
|
get rowData() {
|
|
@@ -2207,16 +2249,22 @@ class DataGridRowComponent extends BaseComponent {
|
|
|
2207
2249
|
//#endregion
|
|
2208
2250
|
//#region Event handlers
|
|
2209
2251
|
onResize(colIndex, event) {
|
|
2210
|
-
if (this.isWidthSet[colIndex]) {
|
|
2211
|
-
return;
|
|
2212
|
-
}
|
|
2213
2252
|
const width = event.contentRect.width;
|
|
2214
|
-
|
|
2253
|
+
// The very first callback can arrive before the grid is laid out and reports zero for every
|
|
2254
|
+
// column; taking that at face value would pin the heading at zero. Once a column has measured
|
|
2255
|
+
// something real, a later zero is believable -- that is a 1fr column collapsing, and the
|
|
2256
|
+
// heading has to collapse with it or every column to its right sits under the wrong one.
|
|
2257
|
+
if (width <= 0 && !this.hasMeasured[colIndex]) {
|
|
2215
2258
|
return;
|
|
2216
2259
|
}
|
|
2217
|
-
|
|
2260
|
+
this.hasMeasured[colIndex] = true;
|
|
2261
|
+
// Reported on every change, not just the first. The body lays the columns out as a CSS grid of
|
|
2262
|
+
// minmax(x, min-content), so a column is only as wide as the content currently rendered --
|
|
2263
|
+
// which virtual scrolling keeps changing. Measuring once and latching left the header copying
|
|
2264
|
+
// a width the body no longer had, and with many columns that drift accumulated into cells
|
|
2265
|
+
// sitting under the wrong heading.
|
|
2266
|
+
if (this.columns[colIndex].realSize !== width) {
|
|
2218
2267
|
this.columns[colIndex].realSize = width;
|
|
2219
|
-
this.isWidthSet[colIndex] = true;
|
|
2220
2268
|
}
|
|
2221
2269
|
}
|
|
2222
2270
|
onResizeSelection(event) {
|
|
@@ -2287,6 +2335,7 @@ class DataGridComponent extends BaseComponent {
|
|
|
2287
2335
|
dataGridDataset = inject(DataGridDataset);
|
|
2288
2336
|
hasFailed = false;
|
|
2289
2337
|
headerRightMargin = 0;
|
|
2338
|
+
headerScrollLeft = 0;
|
|
2290
2339
|
loading = false;
|
|
2291
2340
|
bodyResized$ = new Subject();
|
|
2292
2341
|
bodyResizeObserver;
|
|
@@ -2403,6 +2452,26 @@ class DataGridComponent extends BaseComponent {
|
|
|
2403
2452
|
}
|
|
2404
2453
|
}
|
|
2405
2454
|
ngAfterViewInit() {
|
|
2455
|
+
// The rows scroll sideways inside the CDK viewport while the header sits outside it, so the
|
|
2456
|
+
// header has to be moved by hand or the headings stay behind as the cells travel. Read outside
|
|
2457
|
+
// Angular and written back inside it, because this fires for every frame of a scroll.
|
|
2458
|
+
const viewportElement = this.viewport?.elementRef?.nativeElement;
|
|
2459
|
+
if (viewportElement) {
|
|
2460
|
+
this.ngZone.runOutsideAngular(() => {
|
|
2461
|
+
fromEvent(viewportElement, 'scroll')
|
|
2462
|
+
.pipe(takeUntil(this.destroy$))
|
|
2463
|
+
.subscribe(() => {
|
|
2464
|
+
const scrollLeft = viewportElement.scrollLeft;
|
|
2465
|
+
if (this.headerScrollLeft === scrollLeft) {
|
|
2466
|
+
return;
|
|
2467
|
+
}
|
|
2468
|
+
this.ngZone.run(() => {
|
|
2469
|
+
this.headerScrollLeft = scrollLeft;
|
|
2470
|
+
this.changeDetectorRef.detectChanges();
|
|
2471
|
+
});
|
|
2472
|
+
});
|
|
2473
|
+
});
|
|
2474
|
+
}
|
|
2406
2475
|
this.viewport?.renderedRangeStream
|
|
2407
2476
|
.pipe(takeUntil(this.destroy$))
|
|
2408
2477
|
.subscribe((listRange) => {
|
|
@@ -2455,7 +2524,7 @@ class DataGridComponent extends BaseComponent {
|
|
|
2455
2524
|
return item.key;
|
|
2456
2525
|
}
|
|
2457
2526
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: DataGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2458
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.6", type: DataGridComponent, isStandalone: true, selector: "lib-data-grid", inputs: { disabled: "disabled", lazyLoadRows: "lazyLoadRows", showButtons: "showButtons" }, host: { properties: { "class.no-borders": "showButtons" } }, viewQueries: [{ propertyName: "bodyElement", first: true, predicate: ["body"], descendants: true }, { propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"buttons\"\n*ngIf=\"showButtons\">\n <ng-content select=\"[buttons]\"></ng-content>\n</div>\n\n<div class=\"header\"\n[class.hide]=\"isHideColumns\"\n[style.padding-right.px]=\"headerRightMargin\">\n <div class=\"header-row\">\n <div *ngIf=\"isShowMultiSelect\"\n class=\"header-cell selection\"\n [ngStyle]=\"{\n 'width': selectionColWidth ? selectionColWidth : null\n }\">\n \n </div>\n \n <div *ngFor=\"let column of columns\"\n class=\"header-cell\"\n [ngStyle]=\"{\n '
|
|
2527
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.6", type: DataGridComponent, isStandalone: true, selector: "lib-data-grid", inputs: { disabled: "disabled", lazyLoadRows: "lazyLoadRows", showButtons: "showButtons" }, host: { properties: { "class.no-borders": "showButtons" } }, viewQueries: [{ propertyName: "bodyElement", first: true, predicate: ["body"], descendants: true }, { propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"buttons\"\n*ngIf=\"showButtons\">\n <ng-content select=\"[buttons]\"></ng-content>\n</div>\n\n<div class=\"header\"\n[class.hide]=\"isHideColumns\"\n[style.padding-right.px]=\"headerRightMargin\">\n <!-- Translated by however far the body is scrolled sideways. The rows scroll inside the CDK\n viewport and the header sits outside it, so without this the headings simply stay put\n while the cells move away from them. -->\n <div class=\"header-row\"\n [style.transform]=\"headerScrollLeft ? 'translateX(-' + headerScrollLeft + 'px)' : null\">\n <div *ngIf=\"isShowMultiSelect\"\n class=\"header-cell selection\"\n [ngStyle]=\"{\n 'width': selectionColWidth ? selectionColWidth : null\n }\">\n \n </div>\n \n <!-- A measured zero is a width, not the absence of one: it is a 1fr column that collapsed,\n and its heading has to collapse too. The old test read `realSize ?? 0 > 0`, which binds\n as `realSize ?? (0 > 0)` and so turned zero into no width at all.\n\n Such a heading is removed rather than merely made zero wide, because a flex item still\n takes a gap on each side while the body grid allows the collapsed track only one, and\n that spare gap pushed every heading to its right out by 16px. -->\n <div *ngFor=\"let column of columns\"\n class=\"header-cell\"\n [ngStyle]=\"{\n 'display': column.realSize === 0 ? 'none' : null,\n 'width.px': column.realSize ?? null\n }\">\n <span>{{ column.headerName | translate }}</span>\n </div>\n </div>\n</div>\n\n<div #body\nclass=\"body\"\n[style.min-height.px]=\"bodyMinHeight\">\n <cdk-virtual-scroll-viewport\n [itemSize]=\"configs.rowHeight\"\n [style.grid-template-columns]=\"gridColumns\">\n <lib-data-grid-row #row\n *cdkVirtualFor=\"let row of dataGridDataset.loadedRows; index as i; trackBy: trackByFn\"\n [disabled]=\"disabled\"\n [isFirstRow]=\"isFirstVisibleRow(i)\"\n [rowData]=\"row\"\n [style.height.px]=\"configs.rowHeight\"\n (selectionResized)=\"onSelectionResized($event)\">\n </lib-data-grid-row>\n\n <div *ngIf=\"loading\"\n class=\"loading\"\n [style.height.px]=\"configs.rowHeight\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n \n <span>\n {{ dataGridDataset.configs.loadingDisplayText ?? '' | translate }} \n </span>\n </div>\n \n <div *ngIf=\"!loading && !hasBeenLoaded && lazyLoadRows\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n {{ messageToDisplayWhenLazyLoad | translate }}\n </span>\n </div>\n\n <ng-container *ngIf=\"!loading && hasBeenLoaded && (!hasLoadedRows || hasFailed)\">\n <div *ngIf=\"!hasFailed && !hasLoadedRows && hasMessageToDisplayWhenEmpty && shouldDisplayMessageWhenEmpty\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n {{ messageToDisplayWhenEmpty | translate }}\n </span>\n </div>\n\n <div *ngIf=\"hasFailed\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n <i class=\"fas fa-exclamation-triangle mr-2 text-yellow-600\"></i>{{ messageToDisplayWhenFailed | translate }}\n </span>\n </div>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n</div>", styles: [":host-context{display:flex;-webkit-user-select:none;user-select:none;flex-direction:column;overflow:hidden}:host-context:not(.no-borders){border-radius:.5rem;border-width:1px;border-color:#d1d5dbe6;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}:host-context.no-borders .header .header-row{padding-top:.375rem;padding-bottom:.375rem}:host-context.no-borders .body lib-data-grid-row{padding-top:.25rem;padding-bottom:.25rem}.header-row,lib-data-grid-row,.loading,.message{gap:1rem;padding-left:1rem;padding-right:1rem}.header{overflow:hidden;border-bottom-width:1px;border-color:#d1d5dbe6;background-color:#e5e7eb66;font-weight:700}.header.hide{display:none}.header .header-row{display:flex;flex-direction:row;padding-top:.75rem;padding-bottom:.75rem}.header .header-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header .header-cell:not(.selection){flex:none}.body{position:relative;flex-grow:1}.body cdk-virtual-scroll-viewport{position:absolute;inset:0}.body cdk-virtual-scroll-viewport ::ng-deep .cdk-virtual-scroll-content-wrapper{display:grid;grid-template-columns:inherit}.body lib-data-grid-row{margin-top:-1px;cursor:pointer;border-top-width:1px;border-bottom-width:1px;border-color:#cbd5e180;padding-top:.5rem;padding-bottom:.5rem}.body lib-data-grid-row:nth-child(2n){background-color:#f8fafcb3}.body lib-data-grid-row:hover{background-color:#bfdbfe33}.body lib-data-grid-row.focused{z-index:1;border-color:#94a3b899}.body lib-data-grid-row.selected{position:relative;z-index:10;--tw-border-opacity: 1;border-color:rgb(147 197 253 / var(--tw-border-opacity, 1));background-color:#bfdbfe4d}.body lib-data-grid-row.selected:hover{background-color:#bfdbfe66}.body .loading,.body .message{display:flex;align-items:center;gap:.5rem;white-space:nowrap;height:2.5rem;border-bottom-width:1px;border-color:#cbd5e180;grid-column:1 / -1}.body .loading span,.body .message span{overflow:hidden;text-overflow:ellipsis}.body .loading svg{height:1.5rem;min-height:1.5rem;width:1.5rem;min-width:1.5rem}@keyframes spin{to{transform:rotate(360deg)}}.body .loading svg{animation:spin 1s linear infinite;transition-property:opacity;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.buttons{display:flex;border-top-width:1px;border-bottom-width:1px;border-color:#d1d5dbe6;padding:.25rem}\n"], dependencies: [{ kind: "component", type: DataGridRowComponent, selector: "lib-data-grid-row", inputs: ["disabled", "isFirstRow", "rowData"], outputs: ["selectionResized"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1$2.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1$2.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1$2.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2459
2528
|
}
|
|
2460
2529
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: DataGridComponent, decorators: [{
|
|
2461
2530
|
type: Component,
|
|
@@ -2468,7 +2537,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
|
|
|
2468
2537
|
NgStyle,
|
|
2469
2538
|
ScrollingModule,
|
|
2470
2539
|
TranslatePipe,
|
|
2471
|
-
], template: "<div class=\"buttons\"\n*ngIf=\"showButtons\">\n <ng-content select=\"[buttons]\"></ng-content>\n</div>\n\n<div class=\"header\"\n[class.hide]=\"isHideColumns\"\n[style.padding-right.px]=\"headerRightMargin\">\n <div class=\"header-row\">\n <div *ngIf=\"isShowMultiSelect\"\n class=\"header-cell selection\"\n [ngStyle]=\"{\n 'width': selectionColWidth ? selectionColWidth : null\n }\">\n \n </div>\n \n <div *ngFor=\"let column of columns\"\n class=\"header-cell\"\n [ngStyle]=\"{\n '
|
|
2540
|
+
], template: "<div class=\"buttons\"\n*ngIf=\"showButtons\">\n <ng-content select=\"[buttons]\"></ng-content>\n</div>\n\n<div class=\"header\"\n[class.hide]=\"isHideColumns\"\n[style.padding-right.px]=\"headerRightMargin\">\n <!-- Translated by however far the body is scrolled sideways. The rows scroll inside the CDK\n viewport and the header sits outside it, so without this the headings simply stay put\n while the cells move away from them. -->\n <div class=\"header-row\"\n [style.transform]=\"headerScrollLeft ? 'translateX(-' + headerScrollLeft + 'px)' : null\">\n <div *ngIf=\"isShowMultiSelect\"\n class=\"header-cell selection\"\n [ngStyle]=\"{\n 'width': selectionColWidth ? selectionColWidth : null\n }\">\n \n </div>\n \n <!-- A measured zero is a width, not the absence of one: it is a 1fr column that collapsed,\n and its heading has to collapse too. The old test read `realSize ?? 0 > 0`, which binds\n as `realSize ?? (0 > 0)` and so turned zero into no width at all.\n\n Such a heading is removed rather than merely made zero wide, because a flex item still\n takes a gap on each side while the body grid allows the collapsed track only one, and\n that spare gap pushed every heading to its right out by 16px. -->\n <div *ngFor=\"let column of columns\"\n class=\"header-cell\"\n [ngStyle]=\"{\n 'display': column.realSize === 0 ? 'none' : null,\n 'width.px': column.realSize ?? null\n }\">\n <span>{{ column.headerName | translate }}</span>\n </div>\n </div>\n</div>\n\n<div #body\nclass=\"body\"\n[style.min-height.px]=\"bodyMinHeight\">\n <cdk-virtual-scroll-viewport\n [itemSize]=\"configs.rowHeight\"\n [style.grid-template-columns]=\"gridColumns\">\n <lib-data-grid-row #row\n *cdkVirtualFor=\"let row of dataGridDataset.loadedRows; index as i; trackBy: trackByFn\"\n [disabled]=\"disabled\"\n [isFirstRow]=\"isFirstVisibleRow(i)\"\n [rowData]=\"row\"\n [style.height.px]=\"configs.rowHeight\"\n (selectionResized)=\"onSelectionResized($event)\">\n </lib-data-grid-row>\n\n <div *ngIf=\"loading\"\n class=\"loading\"\n [style.height.px]=\"configs.rowHeight\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n \n <span>\n {{ dataGridDataset.configs.loadingDisplayText ?? '' | translate }} \n </span>\n </div>\n \n <div *ngIf=\"!loading && !hasBeenLoaded && lazyLoadRows\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n {{ messageToDisplayWhenLazyLoad | translate }}\n </span>\n </div>\n\n <ng-container *ngIf=\"!loading && hasBeenLoaded && (!hasLoadedRows || hasFailed)\">\n <div *ngIf=\"!hasFailed && !hasLoadedRows && hasMessageToDisplayWhenEmpty && shouldDisplayMessageWhenEmpty\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n {{ messageToDisplayWhenEmpty | translate }}\n </span>\n </div>\n\n <div *ngIf=\"hasFailed\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n <i class=\"fas fa-exclamation-triangle mr-2 text-yellow-600\"></i>{{ messageToDisplayWhenFailed | translate }}\n </span>\n </div>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n</div>", styles: [":host-context{display:flex;-webkit-user-select:none;user-select:none;flex-direction:column;overflow:hidden}:host-context:not(.no-borders){border-radius:.5rem;border-width:1px;border-color:#d1d5dbe6;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}:host-context.no-borders .header .header-row{padding-top:.375rem;padding-bottom:.375rem}:host-context.no-borders .body lib-data-grid-row{padding-top:.25rem;padding-bottom:.25rem}.header-row,lib-data-grid-row,.loading,.message{gap:1rem;padding-left:1rem;padding-right:1rem}.header{overflow:hidden;border-bottom-width:1px;border-color:#d1d5dbe6;background-color:#e5e7eb66;font-weight:700}.header.hide{display:none}.header .header-row{display:flex;flex-direction:row;padding-top:.75rem;padding-bottom:.75rem}.header .header-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header .header-cell:not(.selection){flex:none}.body{position:relative;flex-grow:1}.body cdk-virtual-scroll-viewport{position:absolute;inset:0}.body cdk-virtual-scroll-viewport ::ng-deep .cdk-virtual-scroll-content-wrapper{display:grid;grid-template-columns:inherit}.body lib-data-grid-row{margin-top:-1px;cursor:pointer;border-top-width:1px;border-bottom-width:1px;border-color:#cbd5e180;padding-top:.5rem;padding-bottom:.5rem}.body lib-data-grid-row:nth-child(2n){background-color:#f8fafcb3}.body lib-data-grid-row:hover{background-color:#bfdbfe33}.body lib-data-grid-row.focused{z-index:1;border-color:#94a3b899}.body lib-data-grid-row.selected{position:relative;z-index:10;--tw-border-opacity: 1;border-color:rgb(147 197 253 / var(--tw-border-opacity, 1));background-color:#bfdbfe4d}.body lib-data-grid-row.selected:hover{background-color:#bfdbfe66}.body .loading,.body .message{display:flex;align-items:center;gap:.5rem;white-space:nowrap;height:2.5rem;border-bottom-width:1px;border-color:#cbd5e180;grid-column:1 / -1}.body .loading span,.body .message span{overflow:hidden;text-overflow:ellipsis}.body .loading svg{height:1.5rem;min-height:1.5rem;width:1.5rem;min-width:1.5rem}@keyframes spin{to{transform:rotate(360deg)}}.body .loading svg{animation:spin 1s linear infinite;transition-property:opacity;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.buttons{display:flex;border-top-width:1px;border-bottom-width:1px;border-color:#d1d5dbe6;padding:.25rem}\n"] }]
|
|
2472
2541
|
}], ctorParameters: () => [], propDecorators: { bodyElement: [{
|
|
2473
2542
|
type: ViewChild,
|
|
2474
2543
|
args: ['body']
|
|
@@ -4013,5 +4082,5 @@ class DateValidators {
|
|
|
4013
4082
|
* Generated bundle index. Do not edit.
|
|
4014
4083
|
*/
|
|
4015
4084
|
|
|
4016
|
-
export { BaseComponent, BaseDataset, CatalogSelectComponent, CatalogService, DataGridComponent, DataGridConfigsProvider, DataGridDataset, DataGridRowComponent, DataProviderService, DateHelpers, DateValidators, EnumTranslatePipe, FormGroupComponent, FormGroupService, FormInputComponent, FormInputGroupComponent, FormService, GridConfigsProvider, GridDataset, GroupAccordionComponent, GroupContainerComponent, GroupScrollSpyComponent, GuidHelper, LibraryModule, ModalComponent, MultiEditorComponent, MultiEditorDataset, MultiSelectComponent, MultiSelectResultDataset, MultiSelectResultGridComponent, ReplaceManyPipe, ReplacePipe, RibbonButtonComponent, RibbonComponent, RibbonGroupChild, RibbonGroupComponent, RouterFormatter, SIDEBAR_CONFIGS, ScrollSpyDirective, SidebarComponent, SidebarConfigs, SidebarMenu, SidebarMenuOpenMode, SidebarService, toSidebarMenuOpenMode };
|
|
4085
|
+
export { BaseComponent, BaseDataset, CatalogSelectComponent, CatalogService, DataGridComponent, DataGridConfigsProvider, DataGridDataset, DataGridRowComponent, DataProviderService, DateHelpers, DateValidators, DisplayControls, EnumTranslatePipe, FormGroupComponent, FormGroupService, FormInputComponent, FormInputGroupComponent, FormService, GridConfigsProvider, GridDataset, GroupAccordionComponent, GroupContainerComponent, GroupScrollSpyComponent, GuidHelper, LibraryModule, ModalComponent, MultiEditorComponent, MultiEditorDataset, MultiSelectComponent, MultiSelectResultDataset, MultiSelectResultGridComponent, ReplaceManyPipe, ReplacePipe, RibbonButtonComponent, RibbonComponent, RibbonGroupChild, RibbonGroupComponent, RouterFormatter, SIDEBAR_CONFIGS, ScrollSpyDirective, SidebarComponent, SidebarConfigs, SidebarMenu, SidebarMenuOpenMode, SidebarService, toSidebarMenuOpenMode };
|
|
4017
4086
|
//# sourceMappingURL=zambon-dev-library.mjs.map
|