@trudb/tru-common-lib 0.2.472 → 0.2.474
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.
|
@@ -8221,11 +8221,8 @@ class TruDataChangeParser {
|
|
|
8221
8221
|
}
|
|
8222
8222
|
else if (entity[key] !== this.checkIfDateTime(change.properties[key], entity[key], entityType.typeName)) {
|
|
8223
8223
|
if (!propertyModified) {
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
entity[key] = newValue;
|
|
8227
|
-
delete originalValues[key];
|
|
8228
|
-
}
|
|
8224
|
+
entity[key] = this.checkIfDateTime(change.properties[key], entity[key], entityType.typeName);
|
|
8225
|
+
delete originalValues[key];
|
|
8229
8226
|
}
|
|
8230
8227
|
else {
|
|
8231
8228
|
let value = this.checkIfDateTime(change.properties[key], entity[key], entityType.typeName);
|
|
@@ -8291,7 +8288,7 @@ class TruDataChangeParser {
|
|
|
8291
8288
|
update = async (payload) => {
|
|
8292
8289
|
await this.isSaving();
|
|
8293
8290
|
var reloadResults = false;
|
|
8294
|
-
payload.changes.forEach(async (change) => {
|
|
8291
|
+
payload.changes.filter((change) => { return change.modifiedRef.toString() !== this.user.activeUserRef.toString(); }).forEach(async (change) => {
|
|
8295
8292
|
var foundEntities = [];
|
|
8296
8293
|
var localEntity = this.findEntityInCache(change);
|
|
8297
8294
|
var globalEntity = this.findEntityInGlobalCache(change);
|
|
@@ -8600,6 +8597,8 @@ class TruDataGrid {
|
|
|
8600
8597
|
rowFocuedOnMousedown = null;
|
|
8601
8598
|
copiedRowData = [];
|
|
8602
8599
|
scrollOffsetCleanup = null;
|
|
8600
|
+
detailResizeCleanup = null;
|
|
8601
|
+
pendingResizeFrameId = null;
|
|
8603
8602
|
constructor(dataContext, componentLookup, searchResultViewManager, appEnvironment, searchViewEventHandler, uiNotification, connectionHub, windowEventHandler, dataGridClipboard, util, app, cdr, hostElement, desktopViewEventNotifier, tabGroupEventNotifier) {
|
|
8604
8603
|
this.dataContext = dataContext;
|
|
8605
8604
|
this.componentLookup = componentLookup;
|
|
@@ -9206,6 +9205,7 @@ class TruDataGrid {
|
|
|
9206
9205
|
if (this.config?.view && this.desktopViewEventNotifier) {
|
|
9207
9206
|
this.subs.push(this.desktopViewEventNotifier.onActiveStateChanged().pipe(skip(1)).subscribe(() => this.resizeGrid()));
|
|
9208
9207
|
}
|
|
9208
|
+
this.setupDetailResizeObservers();
|
|
9209
9209
|
}
|
|
9210
9210
|
ngOnChanges(changes) {
|
|
9211
9211
|
this.runSearch();
|
|
@@ -9213,6 +9213,7 @@ class TruDataGrid {
|
|
|
9213
9213
|
}
|
|
9214
9214
|
ngOnDestroy() {
|
|
9215
9215
|
this.teardownScrollObservers();
|
|
9216
|
+
this.teardownDetailResizeObservers();
|
|
9216
9217
|
this.subs.forEach(s => s.unsubscribe());
|
|
9217
9218
|
}
|
|
9218
9219
|
//this only applies to grids inside detail views and tab containers.
|
|
@@ -9282,6 +9283,71 @@ class TruDataGrid {
|
|
|
9282
9283
|
this.scrollOffsetCleanup = null;
|
|
9283
9284
|
}
|
|
9284
9285
|
};
|
|
9286
|
+
scheduleResizeGrid = () => {
|
|
9287
|
+
if (this.pendingResizeFrameId !== null)
|
|
9288
|
+
return;
|
|
9289
|
+
this.pendingResizeFrameId = window.requestAnimationFrame(() => {
|
|
9290
|
+
this.pendingResizeFrameId = null;
|
|
9291
|
+
this.resizeGrid();
|
|
9292
|
+
});
|
|
9293
|
+
};
|
|
9294
|
+
setupDetailResizeObservers = () => {
|
|
9295
|
+
this.teardownDetailResizeObservers();
|
|
9296
|
+
const gridType = this.gridType;
|
|
9297
|
+
if (gridType === TruDataGridTypes.Search)
|
|
9298
|
+
return;
|
|
9299
|
+
const hostEl = this.hostElement.nativeElement;
|
|
9300
|
+
if (!hostEl || !hostEl.isConnected)
|
|
9301
|
+
return;
|
|
9302
|
+
const detailContent = hostEl.closest('.detail-content');
|
|
9303
|
+
if (!detailContent)
|
|
9304
|
+
return;
|
|
9305
|
+
// Make sure we re-measure when the grid is scrolled into view (common when the initial window height is short).
|
|
9306
|
+
const onScroll = () => this.scheduleResizeGrid();
|
|
9307
|
+
let intersectionObserver = null;
|
|
9308
|
+
if (typeof IntersectionObserver !== 'undefined') {
|
|
9309
|
+
intersectionObserver = new IntersectionObserver((entries) => {
|
|
9310
|
+
if (entries.some(e => e.isIntersecting)) {
|
|
9311
|
+
this.scheduleResizeGrid();
|
|
9312
|
+
}
|
|
9313
|
+
}, { root: detailContent, threshold: 0 });
|
|
9314
|
+
intersectionObserver.observe(hostEl);
|
|
9315
|
+
}
|
|
9316
|
+
else {
|
|
9317
|
+
detailContent.addEventListener('scroll', onScroll, { passive: true });
|
|
9318
|
+
}
|
|
9319
|
+
let resizeObserver = null;
|
|
9320
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
9321
|
+
resizeObserver = new ResizeObserver(() => this.scheduleResizeGrid());
|
|
9322
|
+
resizeObserver.observe(detailContent);
|
|
9323
|
+
}
|
|
9324
|
+
this.detailResizeCleanup = () => {
|
|
9325
|
+
if (intersectionObserver) {
|
|
9326
|
+
intersectionObserver.disconnect();
|
|
9327
|
+
intersectionObserver = null;
|
|
9328
|
+
}
|
|
9329
|
+
else {
|
|
9330
|
+
detailContent.removeEventListener('scroll', onScroll);
|
|
9331
|
+
}
|
|
9332
|
+
if (resizeObserver) {
|
|
9333
|
+
resizeObserver.disconnect();
|
|
9334
|
+
resizeObserver = null;
|
|
9335
|
+
}
|
|
9336
|
+
if (this.pendingResizeFrameId !== null) {
|
|
9337
|
+
window.cancelAnimationFrame(this.pendingResizeFrameId);
|
|
9338
|
+
this.pendingResizeFrameId = null;
|
|
9339
|
+
}
|
|
9340
|
+
this.detailResizeCleanup = null;
|
|
9341
|
+
};
|
|
9342
|
+
// Kick an initial measurement once layout settles.
|
|
9343
|
+
this.scheduleResizeGrid();
|
|
9344
|
+
};
|
|
9345
|
+
teardownDetailResizeObservers = () => {
|
|
9346
|
+
if (this.detailResizeCleanup) {
|
|
9347
|
+
this.detailResizeCleanup();
|
|
9348
|
+
this.detailResizeCleanup = null;
|
|
9349
|
+
}
|
|
9350
|
+
};
|
|
9285
9351
|
//Adjusts grid height to fill available detail space, honoring fill/min/max rows.
|
|
9286
9352
|
//this doesn't affect search grids.
|
|
9287
9353
|
resizeGrid = () => {
|
|
@@ -9300,12 +9366,6 @@ class TruDataGrid {
|
|
|
9300
9366
|
const firstGridTop = siblingGrids.length ? siblingGrids[0].getBoundingClientRect().top : hostEl.getBoundingClientRect().top;
|
|
9301
9367
|
const detailRect = detailContent.getBoundingClientRect();
|
|
9302
9368
|
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
9369
|
const rowHeight = this.gridOptions?.rowHeight ?? 22;
|
|
9310
9370
|
const headerHeight = 25;
|
|
9311
9371
|
const minRows = this.config.minimumRows ?? 0;
|
|
@@ -9318,6 +9378,20 @@ class TruDataGrid {
|
|
|
9318
9378
|
const contentMinPx = Math.max((minRows * rowHeight) + headerHeight, overlayMinPx);
|
|
9319
9379
|
const minPx = contentMinPx + gridChromePx;
|
|
9320
9380
|
const maxPx = typeof maxRows === 'number' ? ((maxRows * rowHeight) + headerHeight + gridChromePx) : undefined;
|
|
9381
|
+
// When the initial window height is short, the grid can start below the visible portion of the detail container.
|
|
9382
|
+
// In that case, we still need a minimum height so the parent can scroll to reveal the grid.
|
|
9383
|
+
if (availableTotal <= 0) {
|
|
9384
|
+
hostEl.style.height = `${minPx}px`;
|
|
9385
|
+
const apiAny = this.api;
|
|
9386
|
+
if (apiAny?.doLayout) {
|
|
9387
|
+
apiAny.doLayout();
|
|
9388
|
+
}
|
|
9389
|
+
return;
|
|
9390
|
+
}
|
|
9391
|
+
const perGridOverhead = 45; // toolbar + statusbar overhead (v6 does something similar i am just porting here)
|
|
9392
|
+
const distributedHeight = siblingGrids.length > 1
|
|
9393
|
+
? (availableTotal - (siblingGrids.length - 1) * perGridOverhead) / siblingGrids.length
|
|
9394
|
+
: availableTotal;
|
|
9321
9395
|
let targetHeight = distributedHeight;
|
|
9322
9396
|
if (!this.config.fill) {
|
|
9323
9397
|
if (maxPx !== undefined && maxPx < targetHeight)
|
|
@@ -11917,17 +11991,19 @@ class TruTabGroup {
|
|
|
11917
11991
|
const list = new QueryList();
|
|
11918
11992
|
list.reset([matTabsFromQueryList]);
|
|
11919
11993
|
this.tabGroup._tabs = list;
|
|
11994
|
+
// Ensure the initially-selected tab is marked active so consumers (e.g. detail grids) can load/size correctly.
|
|
11995
|
+
// MatTabGroup won't emit selectedTabChange on initial render.
|
|
11996
|
+
setTimeout(() => {
|
|
11997
|
+
const selectedIndex = typeof this.tabGroup.selectedIndex === 'number' ? this.tabGroup.selectedIndex : 0;
|
|
11998
|
+
this.setActiveTabByIndex(selectedIndex);
|
|
11999
|
+
}, 0);
|
|
11920
12000
|
}
|
|
11921
12001
|
onChange(event) {
|
|
11922
|
-
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
else {
|
|
11928
|
-
tab.notifyListeners(false);
|
|
11929
|
-
}
|
|
11930
|
-
});
|
|
12002
|
+
this.setActiveTabByIndex(event.index);
|
|
12003
|
+
}
|
|
12004
|
+
setActiveTabByIndex(selectedIndex) {
|
|
12005
|
+
const allTabs = this.tabs?.toArray?.() ?? [];
|
|
12006
|
+
allTabs.forEach((tab, index) => tab.notifyListeners(index === selectedIndex));
|
|
11931
12007
|
}
|
|
11932
12008
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TruTabGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11933
12009
|
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 });
|