@trudb/tru-common-lib 0.2.473 → 0.2.476
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.
|
@@ -8600,6 +8600,8 @@ class TruDataGrid {
|
|
|
8600
8600
|
rowFocuedOnMousedown = null;
|
|
8601
8601
|
copiedRowData = [];
|
|
8602
8602
|
scrollOffsetCleanup = null;
|
|
8603
|
+
detailResizeCleanup = null;
|
|
8604
|
+
pendingResizeFrameId = null;
|
|
8603
8605
|
constructor(dataContext, componentLookup, searchResultViewManager, appEnvironment, searchViewEventHandler, uiNotification, connectionHub, windowEventHandler, dataGridClipboard, util, app, cdr, hostElement, desktopViewEventNotifier, tabGroupEventNotifier) {
|
|
8604
8606
|
this.dataContext = dataContext;
|
|
8605
8607
|
this.componentLookup = componentLookup;
|
|
@@ -9206,6 +9208,7 @@ class TruDataGrid {
|
|
|
9206
9208
|
if (this.config?.view && this.desktopViewEventNotifier) {
|
|
9207
9209
|
this.subs.push(this.desktopViewEventNotifier.onActiveStateChanged().pipe(skip(1)).subscribe(() => this.resizeGrid()));
|
|
9208
9210
|
}
|
|
9211
|
+
this.setupDetailResizeObservers();
|
|
9209
9212
|
}
|
|
9210
9213
|
ngOnChanges(changes) {
|
|
9211
9214
|
this.runSearch();
|
|
@@ -9213,6 +9216,7 @@ class TruDataGrid {
|
|
|
9213
9216
|
}
|
|
9214
9217
|
ngOnDestroy() {
|
|
9215
9218
|
this.teardownScrollObservers();
|
|
9219
|
+
this.teardownDetailResizeObservers();
|
|
9216
9220
|
this.subs.forEach(s => s.unsubscribe());
|
|
9217
9221
|
}
|
|
9218
9222
|
//this only applies to grids inside detail views and tab containers.
|
|
@@ -9282,6 +9286,71 @@ class TruDataGrid {
|
|
|
9282
9286
|
this.scrollOffsetCleanup = null;
|
|
9283
9287
|
}
|
|
9284
9288
|
};
|
|
9289
|
+
scheduleResizeGrid = () => {
|
|
9290
|
+
if (this.pendingResizeFrameId !== null)
|
|
9291
|
+
return;
|
|
9292
|
+
this.pendingResizeFrameId = window.requestAnimationFrame(() => {
|
|
9293
|
+
this.pendingResizeFrameId = null;
|
|
9294
|
+
this.resizeGrid();
|
|
9295
|
+
});
|
|
9296
|
+
};
|
|
9297
|
+
setupDetailResizeObservers = () => {
|
|
9298
|
+
this.teardownDetailResizeObservers();
|
|
9299
|
+
const gridType = this.gridType;
|
|
9300
|
+
if (gridType === TruDataGridTypes.Search)
|
|
9301
|
+
return;
|
|
9302
|
+
const hostEl = this.hostElement.nativeElement;
|
|
9303
|
+
if (!hostEl || !hostEl.isConnected)
|
|
9304
|
+
return;
|
|
9305
|
+
const detailContent = hostEl.closest('.detail-content');
|
|
9306
|
+
if (!detailContent)
|
|
9307
|
+
return;
|
|
9308
|
+
// Make sure we re-measure when the grid is scrolled into view (common when the initial window height is short).
|
|
9309
|
+
const onScroll = () => this.scheduleResizeGrid();
|
|
9310
|
+
let intersectionObserver = null;
|
|
9311
|
+
if (typeof IntersectionObserver !== 'undefined') {
|
|
9312
|
+
intersectionObserver = new IntersectionObserver((entries) => {
|
|
9313
|
+
if (entries.some(e => e.isIntersecting)) {
|
|
9314
|
+
this.scheduleResizeGrid();
|
|
9315
|
+
}
|
|
9316
|
+
}, { root: detailContent, threshold: 0 });
|
|
9317
|
+
intersectionObserver.observe(hostEl);
|
|
9318
|
+
}
|
|
9319
|
+
else {
|
|
9320
|
+
detailContent.addEventListener('scroll', onScroll, { passive: true });
|
|
9321
|
+
}
|
|
9322
|
+
let resizeObserver = null;
|
|
9323
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
9324
|
+
resizeObserver = new ResizeObserver(() => this.scheduleResizeGrid());
|
|
9325
|
+
resizeObserver.observe(detailContent);
|
|
9326
|
+
}
|
|
9327
|
+
this.detailResizeCleanup = () => {
|
|
9328
|
+
if (intersectionObserver) {
|
|
9329
|
+
intersectionObserver.disconnect();
|
|
9330
|
+
intersectionObserver = null;
|
|
9331
|
+
}
|
|
9332
|
+
else {
|
|
9333
|
+
detailContent.removeEventListener('scroll', onScroll);
|
|
9334
|
+
}
|
|
9335
|
+
if (resizeObserver) {
|
|
9336
|
+
resizeObserver.disconnect();
|
|
9337
|
+
resizeObserver = null;
|
|
9338
|
+
}
|
|
9339
|
+
if (this.pendingResizeFrameId !== null) {
|
|
9340
|
+
window.cancelAnimationFrame(this.pendingResizeFrameId);
|
|
9341
|
+
this.pendingResizeFrameId = null;
|
|
9342
|
+
}
|
|
9343
|
+
this.detailResizeCleanup = null;
|
|
9344
|
+
};
|
|
9345
|
+
// Kick an initial measurement once layout settles.
|
|
9346
|
+
this.scheduleResizeGrid();
|
|
9347
|
+
};
|
|
9348
|
+
teardownDetailResizeObservers = () => {
|
|
9349
|
+
if (this.detailResizeCleanup) {
|
|
9350
|
+
this.detailResizeCleanup();
|
|
9351
|
+
this.detailResizeCleanup = null;
|
|
9352
|
+
}
|
|
9353
|
+
};
|
|
9285
9354
|
//Adjusts grid height to fill available detail space, honoring fill/min/max rows.
|
|
9286
9355
|
//this doesn't affect search grids.
|
|
9287
9356
|
resizeGrid = () => {
|
|
@@ -9300,12 +9369,6 @@ class TruDataGrid {
|
|
|
9300
9369
|
const firstGridTop = siblingGrids.length ? siblingGrids[0].getBoundingClientRect().top : hostEl.getBoundingClientRect().top;
|
|
9301
9370
|
const detailRect = detailContent.getBoundingClientRect();
|
|
9302
9371
|
const availableTotal = detailContent.clientHeight - (firstGridTop - detailRect.top) - 10; // small bottom padding
|
|
9303
|
-
if (availableTotal <= 0)
|
|
9304
|
-
return;
|
|
9305
|
-
const perGridOverhead = 45; // toolbar + statusbar overhead (v6 does something similar i am just porting here)
|
|
9306
|
-
const distributedHeight = siblingGrids.length > 1
|
|
9307
|
-
? (availableTotal - (siblingGrids.length - 1) * perGridOverhead) / siblingGrids.length
|
|
9308
|
-
: availableTotal;
|
|
9309
9372
|
const rowHeight = this.gridOptions?.rowHeight ?? 22;
|
|
9310
9373
|
const headerHeight = 25;
|
|
9311
9374
|
const minRows = this.config.minimumRows ?? 0;
|
|
@@ -9318,6 +9381,20 @@ class TruDataGrid {
|
|
|
9318
9381
|
const contentMinPx = Math.max((minRows * rowHeight) + headerHeight, overlayMinPx);
|
|
9319
9382
|
const minPx = contentMinPx + gridChromePx;
|
|
9320
9383
|
const maxPx = typeof maxRows === 'number' ? ((maxRows * rowHeight) + headerHeight + gridChromePx) : undefined;
|
|
9384
|
+
// When the initial window height is short, the grid can start below the visible portion of the detail container.
|
|
9385
|
+
// In that case, we still need a minimum height so the parent can scroll to reveal the grid.
|
|
9386
|
+
if (availableTotal <= 0) {
|
|
9387
|
+
hostEl.style.height = `${minPx}px`;
|
|
9388
|
+
const apiAny = this.api;
|
|
9389
|
+
if (apiAny?.doLayout) {
|
|
9390
|
+
apiAny.doLayout();
|
|
9391
|
+
}
|
|
9392
|
+
return;
|
|
9393
|
+
}
|
|
9394
|
+
const perGridOverhead = 45; // toolbar + statusbar overhead (v6 does something similar i am just porting here)
|
|
9395
|
+
const distributedHeight = siblingGrids.length > 1
|
|
9396
|
+
? (availableTotal - (siblingGrids.length - 1) * perGridOverhead) / siblingGrids.length
|
|
9397
|
+
: availableTotal;
|
|
9321
9398
|
let targetHeight = distributedHeight;
|
|
9322
9399
|
if (!this.config.fill) {
|
|
9323
9400
|
if (maxPx !== undefined && maxPx < targetHeight)
|
|
@@ -11917,17 +11994,19 @@ class TruTabGroup {
|
|
|
11917
11994
|
const list = new QueryList();
|
|
11918
11995
|
list.reset([matTabsFromQueryList]);
|
|
11919
11996
|
this.tabGroup._tabs = list;
|
|
11997
|
+
// Ensure the initially-selected tab is marked active so consumers (e.g. detail grids) can load/size correctly.
|
|
11998
|
+
// MatTabGroup won't emit selectedTabChange on initial render.
|
|
11999
|
+
setTimeout(() => {
|
|
12000
|
+
const selectedIndex = typeof this.tabGroup.selectedIndex === 'number' ? this.tabGroup.selectedIndex : 0;
|
|
12001
|
+
this.setActiveTabByIndex(selectedIndex);
|
|
12002
|
+
}, 0);
|
|
11920
12003
|
}
|
|
11921
12004
|
onChange(event) {
|
|
11922
|
-
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
else {
|
|
11928
|
-
tab.notifyListeners(false);
|
|
11929
|
-
}
|
|
11930
|
-
});
|
|
12005
|
+
this.setActiveTabByIndex(event.index);
|
|
12006
|
+
}
|
|
12007
|
+
setActiveTabByIndex(selectedIndex) {
|
|
12008
|
+
const allTabs = this.tabs?.toArray?.() ?? [];
|
|
12009
|
+
allTabs.forEach((tab, index) => tab.notifyListeners(index === selectedIndex));
|
|
11931
12010
|
}
|
|
11932
12011
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TruTabGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11933
12012
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: TruTabGroup, isStandalone: true, selector: "tru-tab-group", queries: [{ propertyName: "tabs", predicate: TruTab }], viewQueries: [{ propertyName: "tabGroup", first: true, predicate: MatTabGroup, descendants: true }], ngImport: i0, template: "<mat-tab-group #tabGroup\r\n (selectedTabChange)=\"onChange($event)\"\r\n animationDuration=\"0ms\">\r\n <ng-content #outlet></ng-content>\r\n</mat-tab-group>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }], encapsulation: i0.ViewEncapsulation.None });
|