From 6f5c86281942882e3d115ee55e50212df83d5c24 Mon Sep 17 00:00:00 2001 From: ark_65 Date: Wed, 5 Jul 2023 14:13:27 +0800 Subject: [PATCH] fix: fix misalignment when scrollbar scrolls to the edge (#389) * fix: fix misalignment when scrollbar scrolls to the edge * fix: fix misalignment when scrollbar scrolls to the edge * fix: fix misalignment when scrollbar scrolls to the edge * fix: fix misalignment when scrollbar scrolls to the edge * fix: update unit test --- .../src/components/bar/test/bar.drag.spec.ts | 3 +++ .../src/components/table/test/table.spec.ts | 4 +++- packages/gantt/src/gantt.component.html | 9 +++++--- packages/gantt/src/gantt.component.ts | 20 +++++++++++++++--- packages/gantt/src/root.component.html | 9 +++++--- packages/gantt/src/root.component.ts | 21 ++++++++++++++++++- .../gantt/src/test/gantt.component.spec.ts | 5 ++++- 7 files changed, 59 insertions(+), 12 deletions(-) diff --git a/packages/gantt/src/components/bar/test/bar.drag.spec.ts b/packages/gantt/src/components/bar/test/bar.drag.spec.ts index d67041f3..1f95a5ca 100644 --- a/packages/gantt/src/components/bar/test/bar.drag.spec.ts +++ b/packages/gantt/src/components/bar/test/bar.drag.spec.ts @@ -168,6 +168,7 @@ describe('bar-drag', () => { it('should bar drag', fakeAsync(() => { const bar = fixture.debugElement.queryAll(By.directive(NgxGanttBarComponent))[0]; dragEvent(fixture, bar.nativeElement); + tick(200); expect(bar.componentInstance.item.start.getUnixTime()).toEqual(new GanttDate('2020-04-21 00:00:00').getUnixTime()); expect(bar.componentInstance.item.end.getUnixTime()).toEqual(new GanttDate('2020-06-26 23:59:59').getUnixTime()); })); @@ -176,6 +177,7 @@ describe('bar-drag', () => { const bar = fixture.debugElement.queryAll(By.directive(NgxGanttBarComponent))[1]; const firstHandleElement = bar.queryAll(By.css('.drag-handles .handle'))[0].nativeElement; dragEvent(fixture, firstHandleElement, bar.nativeElement); + tick(200); expect(bar.componentInstance.item.start.getUnixTime()).toEqual(new GanttDate('2020-05-14 00:00:00').getUnixTime()); })); @@ -183,6 +185,7 @@ describe('bar-drag', () => { const bar = fixture.debugElement.queryAll(By.directive(NgxGanttBarComponent))[1]; const lastHandleElement = bar.queryAll(By.css('.drag-handles .handle'))[1].nativeElement; dragEvent(fixture, lastHandleElement, bar.nativeElement); + tick(200); expect(bar.componentInstance.item.end.getUnixTime()).toEqual(new GanttDate('2020-07-15 23:59:59').getUnixTime()); })); diff --git a/packages/gantt/src/components/table/test/table.spec.ts b/packages/gantt/src/components/table/test/table.spec.ts index ade36d95..b18c5f20 100644 --- a/packages/gantt/src/components/table/test/table.spec.ts +++ b/packages/gantt/src/components/table/test/table.spec.ts @@ -1,4 +1,4 @@ -import { fakeAsync, TestBed, ComponentFixture, async, inject, flush } from '@angular/core/testing'; +import { fakeAsync, TestBed, ComponentFixture, async, flush, tick } from '@angular/core/testing'; import { Component, ViewChild, DebugElement } from '@angular/core'; import { NgxGanttModule } from 'ngx-gantt'; import { By } from '@angular/platform-browser'; @@ -152,6 +152,7 @@ describe('GanttTable', () => { ganttTable.query(By.css('.gantt-table-item')).nativeNode.click(); fixture.detectChanges(); + tick(200); expect(selectionModel.hasValue()).toBeTrue(); expect(selectionModel.selected[0]).toEqual(items[0].id); })); @@ -163,6 +164,7 @@ describe('GanttTable', () => { const mainItemNode = ganttMain.query(By.css('.gantt-item')).nativeNode; itemNode.click(); fixture.detectChanges(); + tick(200); expect(itemNode.classList).toContain('gantt-table-item-active'); expect(mainItemNode.classList).toContain('gantt-main-item-active'); })); diff --git a/packages/gantt/src/gantt.component.html b/packages/gantt/src/gantt.component.html index 15a856e4..ab876dda 100644 --- a/packages/gantt/src/gantt.component.html +++ b/packages/gantt/src/gantt.component.html @@ -2,7 +2,7 @@
- +
@@ -15,7 +15,7 @@ [maxBufferPx]="styles.lineHeight * 20" > -
+
- +
, cdr: ChangeDetectorRef, ngZone: NgZone, + private viewportRuler: ViewportRuler, @Optional() private printService: GanttPrintService, @Inject(GANTT_GLOBAL_CONFIG) config: GanttGlobalConfig ) { @@ -186,6 +188,18 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, } } + ngAfterViewChecked() { + if (this.virtualScrollEnabled && this.viewportRuler && this.virtualScroll.getRenderedRange().end > 0) { + this.ngZone.runOutsideAngular(() => { + setTimeout(() => { + this.ganttRoot.verticalScrollbarWidth = + this.virtualScroll.elementRef.nativeElement.offsetWidth - this.virtualScroll.elementRef.nativeElement.clientWidth; + this.cdr.markForCheck(); + }); + }); + } + } + private buildFlatItems() { const virtualData = []; if (this.groups.length) { diff --git a/packages/gantt/src/root.component.html b/packages/gantt/src/root.component.html index 9675bc8b..a9d9745a 100644 --- a/packages/gantt/src/root.component.html +++ b/packages/gantt/src/root.component.html @@ -1,11 +1,14 @@ -
+
- - + +
diff --git a/packages/gantt/src/root.component.ts b/packages/gantt/src/root.component.ts index d19952db..0d84e220 100644 --- a/packages/gantt/src/root.component.ts +++ b/packages/gantt/src/root.component.ts @@ -9,7 +9,8 @@ import { Input, Optional, OnDestroy, - ViewChild + ViewChild, + HostListener } from '@angular/core'; import { GanttDomService, ScrollDirection } from './gantt-dom.service'; import { GanttDragContainer } from './gantt-drag-container'; @@ -39,12 +40,21 @@ export class NgxGanttRootComponent implements OnInit, OnDestroy { /** The native `` element. */ @ViewChild(GanttDragBackdropComponent, { static: true, read: ElementRef }) backdrop: ElementRef; + verticalScrollbarWidth = 0; + + horizontalScrollbarHeight = 0; + private unsubscribe$ = new Subject(); private get view() { return this.ganttUpper.view; } + @HostListener('window:resize') + onWindowResize() { + this.updateScrollBarOffset(); + } + constructor( private elementRef: ElementRef, private ngZone: NgZone, @@ -76,10 +86,19 @@ export class NgxGanttRootComponent implements OnInit, OnDestroy { this.ganttUpper.viewChange.pipe(startWith(null), takeUntil(this.unsubscribe$)).subscribe(() => { this.scrollToToday(); }); + this.updateScrollBarOffset(); }); }); } + updateScrollBarOffset() { + const ganttMainContainer = this.dom.mainContainer as HTMLElement; + const verticalScrollbarWidth = ganttMainContainer.offsetWidth - ganttMainContainer.clientWidth; + const horizontalScrollbarHeight = ganttMainContainer.offsetHeight - ganttMainContainer.clientHeight; + this.verticalScrollbarWidth = verticalScrollbarWidth; + this.horizontalScrollbarHeight = horizontalScrollbarHeight; + } + ngOnDestroy(): void { this.unsubscribe$.next(); } diff --git a/packages/gantt/src/test/gantt.component.spec.ts b/packages/gantt/src/test/gantt.component.spec.ts index 44e3bb58..184345c7 100644 --- a/packages/gantt/src/test/gantt.component.spec.ts +++ b/packages/gantt/src/test/gantt.component.spec.ts @@ -451,6 +451,7 @@ describe('ngx-gantt', () => { ganttComponentInstance.loading = false; fixture.detectChanges(); loaderDom = fixture.debugElement.query(By.directive(GanttLoaderComponent)); + tick(200); expect(loaderDom).toBeFalsy(); })); @@ -471,15 +472,17 @@ describe('ngx-gantt', () => { ganttComponentInstance.loading = false; fixture.detectChanges(); loaderDom = fixture.debugElement.query(By.directive(GanttLoaderComponent)); + tick(200); expect(loaderDom).toBeFalsy(); })); - it('should column inherits the class when gantt-table-column sets class"', fakeAsync(() => { + it('should column inherits the class when gantt-table-column sets class', fakeAsync(() => { const newItems = mockItems.slice(0, 1); ganttComponentInstance.items = [...newItems]; fixture.detectChanges(); const ganttTable: DebugElement = ganttDebugElement.query(By.directive(GanttTableBodyComponent)); const ganttTableColumn = ganttTable.query(By.css('.gantt-table-column')).nativeElement; + tick(200); expect(ganttTableColumn.classList).toContain('title-name'); expect(ganttTableColumn.classList).toContain('title-name-2'); expect(ganttTableColumn.classList).toContain('title-name-3');