diff --git a/example/src/app/gantt/gantt.component.html b/example/src/app/gantt/gantt.component.html index 27f524e1..b15dd463 100644 --- a/example/src/app/gantt/gantt.component.html +++ b/example/src/app/gantt/gantt.component.html @@ -45,7 +45,7 @@ (linkDragEnded)="linkDragEnded($event)" > - + {{ item.start * 1000 | date : 'yyyy-MM-dd' }} @@ -53,7 +53,7 @@ {{ item.title }} - + {{ item.end * 1000 | date : 'yyyy-MM-dd' }} diff --git a/example/src/app/gantt/gantt.component.ts b/example/src/app/gantt/gantt.component.ts index 0542ddc9..ac62d39a 100644 --- a/example/src/app/gantt/gantt.component.ts +++ b/example/src/app/gantt/gantt.component.ts @@ -59,7 +59,7 @@ export class AppGanttExampleComponent implements OnInit, AfterViewInit { { id: '000000', title: 'Task 0', start: 1627729997, end: 1628421197, expandable: true }, // { id: '000001', title: 'Task 1', start: 1617361997, end: 1625483597, links: ['000003', '000004', '000000'], expandable: true }, { id: '000001', title: 'Task 1', start: 1617361997, end: 1625483597, links: ['000003', '000004', '0000029'], expandable: true }, - { id: '000002', title: 'Task 2', start: 1610536397, end: 1610622797 }, + { id: '000002', title: 'Task 2', start: 1610536397, end: 1610622797, progress: 0.5 }, { id: '000003', title: 'Task 3', start: 1628507597, end: 1633345997, expandable: true }, { id: '000004', title: 'Task 4', start: 1624705997, expandable: true }, { id: '000005', title: 'Task 5', start: 1628075597, end: 1629544397, color: '#709dc1' }, @@ -134,7 +134,6 @@ export class AppGanttExampleComponent implements OnInit, AfterViewInit { dragEnded(event: GanttDragEvent) { this.thyNotify.info('Event: dragEnded', `修改了 [${event.item.title}] 的时间`); - // this.items = [...this.items]; } selectedChange(event: GanttSelectedEvent) { diff --git a/packages/gantt/src/components/calendar/grid/calendar-grid.component.ts b/packages/gantt/src/components/calendar/grid/calendar-grid.component.ts index 6f591630..5ef1bd1b 100644 --- a/packages/gantt/src/components/calendar/grid/calendar-grid.component.ts +++ b/packages/gantt/src/components/calendar/grid/calendar-grid.component.ts @@ -1,15 +1,4 @@ -import { - Component, - OnInit, - HostBinding, - OnChanges, - SimpleChanges, - OnDestroy, - NgZone, - Inject, - ElementRef, - AfterViewInit -} from '@angular/core'; +import { Component, OnInit, HostBinding, OnChanges, SimpleChanges, OnDestroy, NgZone, Inject, ElementRef } from '@angular/core'; import { GanttDatePoint } from '../../../class/date-point'; import { Subject, merge } from 'rxjs'; import { take, takeUntil } from 'rxjs/operators'; @@ -26,7 +15,7 @@ const mainHeight = 5000; selector: 'gantt-calendar-grid', templateUrl: './calendar-grid.component.html' }) -export class GanttCalendarGridComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy { +export class GanttCalendarGridComponent implements OnInit, OnDestroy { get view() { return this.ganttUpper.view; } @@ -74,10 +63,6 @@ export class GanttCalendarGridComponent implements OnInit, AfterViewInit, OnChan }); } - ngAfterViewInit() {} - - ngOnChanges(changes: SimpleChanges): void {} - trackBy(point: GanttDatePoint, index: number) { return point.text || index; } diff --git a/packages/gantt/src/components/table/body/gantt-table-body.component.html b/packages/gantt/src/components/table/body/gantt-table-body.component.html index 6d849582..9fdaca65 100644 --- a/packages/gantt/src/components/table/body/gantt-table-body.component.html +++ b/packages/gantt/src/components/table/body/gantt-table-body.component.html @@ -39,7 +39,7 @@ [ngTemplateOutletContext]="{ $implicit: data.origin, item: data.origin }" > -
+
; - +export class GanttTableBodyComponent implements OnInit, OnDestroy { public hasGroup: boolean; public flatData: (GanttGroupInternal | GanttItemInternal)[]; public hasShowExpandIcon = false; + private unsubscribe$ = new Subject(); + @Input() set tempData(data: (GanttGroupInternal | GanttItemInternal)[]) { const firstData = data[0]; if (firstData && firstData.hasOwnProperty('items')) { @@ -27,19 +40,7 @@ export class GanttTableBodyComponent implements OnInit { this.flatData = data; } - @Input() - set columns(columns: QueryList) { - this.hasShowExpandIcon = false; - columns.forEach((column) => { - if (!column.columnWidth) { - column.columnWidth = coerceCssPixelValue(defaultColumnWidth); - } - if (column.showExpandIcon) { - this.hasShowExpandIcon = true; - } - }); - this.columnList = columns; - } + @Input() columns: QueryList; @Input() groupTemplate: TemplateRef; @@ -57,10 +58,29 @@ export class GanttTableBodyComponent implements OnInit { constructor( @Inject(GANTT_ABSTRACT_TOKEN) public gantt: GanttAbstractComponent, - @Inject(GANTT_UPPER_TOKEN) public ganttUpper: GanttUpper + @Inject(GANTT_UPPER_TOKEN) public ganttUpper: GanttUpper, + private cdr: ChangeDetectorRef ) {} - ngOnInit() {} + ngOnInit() { + this.columnsChange(); + this.columns.changes.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { + this.columnsChange(); + this.cdr.detectChanges(); + }); + } + + private columnsChange() { + this.hasShowExpandIcon = false; + this.columns.forEach((column) => { + if (!column.columnWidth) { + column.columnWidth = coerceCssPixelValue(defaultColumnWidth); + } + if (column.showExpandIcon) { + this.hasShowExpandIcon = true; + } + }); + } expandGroup(group: GanttGroupInternal) { this.gantt.expandGroup(group); @@ -74,4 +94,9 @@ export class GanttTableBodyComponent implements OnInit { trackBy(item: GanttGroupInternal | GanttItemInternal, index: number) { return item.id || index; } + + ngOnDestroy() { + this.unsubscribe$.next(); + this.unsubscribe$.complete(); + } } diff --git a/packages/gantt/src/components/table/gantt-table.scss b/packages/gantt/src/components/table/gantt-table.scss index 509e3fed..e6a0c58b 100644 --- a/packages/gantt/src/components/table/gantt-table.scss +++ b/packages/gantt/src/components/table/gantt-table.scss @@ -9,9 +9,9 @@ position: relative; z-index: 3; border-right: 1px solid variables.$gantt-border-color; - .gantt-table-column { font-weight: 400; + z-index: 1; } } @@ -54,10 +54,6 @@ .gantt-table-column { display: flex; padding: variables.$gantt-table-td-padding; - - &:last-child { - border-right: none; - } } .gantt-table-column-content { diff --git a/packages/gantt/src/components/table/header/gantt-table-header.component.html b/packages/gantt/src/components/table/header/gantt-table-header.component.html index ee25b0f4..2c7e7a9a 100644 --- a/packages/gantt/src/components/table/header/gantt-table-header.component.html +++ b/packages/gantt/src/components/table/header/gantt-table-header.component.html @@ -1,17 +1,19 @@ -
- - - {{ column.name }} - -
+
+
+ + + {{ column.name }} + +
+
; - +export class GanttTableHeaderComponent implements OnInit, OnDestroy { public dragStartLeft: number; public tableWidth = 0; - @Input() - set columns(columns: QueryList) { - columns.forEach((column) => { - if (!column.columnWidth) { - column.columnWidth = coerceCssPixelValue(defaultColumnWidth); - } - }); - this.columnList = columns; - } + private unsubscribe$ = new Subject(); + + @Input() columns: QueryList; @ViewChild('dragLine', { static: true }) draglineElementRef: ElementRef; @HostBinding('class') className = `gantt-table-header gantt-table-row`; - constructor(private elementRef: ElementRef, @Inject(GANTT_ABSTRACT_TOKEN) private gantt: GanttAbstractComponent) {} - - ngOnInit() {} + constructor( + private elementRef: ElementRef, + @Inject(GANTT_ABSTRACT_TOKEN) private gantt: GanttAbstractComponent, + private cdr: ChangeDetectorRef + ) {} + + ngOnInit() { + this.columnsChange(); + this.columns.changes.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { + this.columnsChange(); + this.cdr.detectChanges(); + }); + } - ngAfterViewInit() { - this.tableWidth = this.elementRef.nativeElement.getBoundingClientRect().width; + private columnsChange() { + let tableWidth = 0; + this.columns.forEach((column) => { + if (!column.columnWidth) { + column.columnWidth = coerceCssPixelValue(defaultColumnWidth); + } + tableWidth += Number(column.columnWidth.replace('px', '')); + }); + this.tableWidth = tableWidth; } private dragFixed(config: DragFixedConfig) { @@ -75,7 +96,7 @@ export class GanttTableHeaderComponent implements OnInit, AfterViewInit { } else { originWidth = this.elementRef.nativeElement.getBoundingClientRect().width; movedWidth = originWidth + (left - this.dragStartLeft); - minWidth = minColumnWidth * this.columnList.length; + minWidth = minColumnWidth * this.columns.length; } this.dragFixed({ @@ -96,10 +117,11 @@ export class GanttTableHeaderComponent implements OnInit, AfterViewInit { const columnWidth = Math.max(width || 0, minColumnWidth); column.columnWidth = coerceCssPixelValue(columnWidth); if (this.gantt.table) { - this.gantt.table.columnChanges.emit({ columns: this.columnList }); + this.gantt.table.columnChanges.emit({ columns: this.columns }); } this.tableWidth = this.tableWidth - beforeWidth + columnWidth; + console.log(this.tableWidth); this.hideAuxiliaryLine(); event.source.reset(); } @@ -110,7 +132,7 @@ export class GanttTableHeaderComponent implements OnInit, AfterViewInit { const tableWidth = this.elementRef.nativeElement.getBoundingClientRect().width; const dragWidth = left - this.dragStartLeft; let tempWidth = 0; - this.columnList.forEach((column) => { + this.columns.forEach((column) => { const lastColumnWidth = parseInt(column.columnWidth, 10); const distributeWidth = parseInt(String(dragWidth * (lastColumnWidth / tableWidth)), 10); const columnWidth = Math.max(lastColumnWidth + distributeWidth || 0, minColumnWidth); @@ -119,7 +141,7 @@ export class GanttTableHeaderComponent implements OnInit, AfterViewInit { }); this.tableWidth = tempWidth; if (this.gantt.table) { - this.gantt.table.columnChanges.emit({ columns: this.columnList }); + this.gantt.table.columnChanges.emit({ columns: this.columns }); } this.hideAuxiliaryLine(); @@ -137,4 +159,9 @@ export class GanttTableHeaderComponent implements OnInit, AfterViewInit { private hideAuxiliaryLine() { this.draglineElementRef.nativeElement.style.display = 'none'; } + + ngOnDestroy() { + this.unsubscribe$.next(); + this.unsubscribe$.complete(); + } } diff --git a/packages/gantt/src/gantt-upper.ts b/packages/gantt/src/gantt-upper.ts index 56321095..e478755c 100644 --- a/packages/gantt/src/gantt-upper.ts +++ b/packages/gantt/src/gantt-upper.ts @@ -292,6 +292,14 @@ export abstract class GanttUpper implements OnChanges, OnInit, OnDestroy { return new SelectionModel(this.multiple, []); } + expandGroups(expanded: boolean) { + this.groups.forEach((group) => { + group.setExpand(expanded); + }); + this.expandChange.next(null); + this.cdr.detectChanges(); + } + ngOnInit() { this.styles = Object.assign({}, defaultStyles, this.styles); this.viewOptions.dateFormat = Object.assign({}, defaultConfig.dateFormat, this.config.dateFormat, this.viewOptions.dateFormat); @@ -379,21 +387,21 @@ export abstract class GanttUpper implements OnChanges, OnInit, OnDestroy { this.cdr.detectChanges(); } - // expandGroup(group: GanttGroupInternal) { - // group.setExpand(!group.expanded); - // this.expandChange.emit(group); - // this.cdr.detectChanges(); - // } + // public functions - // // public functions + expandGroup(group: GanttGroupInternal) { + group.setExpand(!group.expanded); + this.expandChange.emit(group); + this.cdr.detectChanges(); + } - // expandAll() { - // this.expandGroups(true); - // } + expandAll() { + this.expandGroups(true); + } - // collapseAll() { - // this.expandGroups(false); - // } + collapseAll() { + this.expandGroups(false); + } getGanttItem(id: string) { return this.getGanttItems([id])[0] || null; diff --git a/packages/gantt/src/gantt.component.html b/packages/gantt/src/gantt.component.html index 1e9bde5b..46a1597f 100644 --- a/packages/gantt/src/gantt.component.html +++ b/packages/gantt/src/gantt.component.html @@ -13,17 +13,19 @@ [maxBufferPx]="styles.lineHeight * 20" > -
+
- +
+ +
@@ -43,5 +45,5 @@
- + diff --git a/packages/gantt/src/gantt.component.scss b/packages/gantt/src/gantt.component.scss index 2c0166a2..75a9d1b6 100644 --- a/packages/gantt/src/gantt.component.scss +++ b/packages/gantt/src/gantt.component.scss @@ -90,6 +90,9 @@ right: 0; bottom: 0; z-index: 2; + // 兼容火狐浏览器 + overflow: auto; + overflow: overlay; .cdk-virtual-scroll-content-wrapper { width: 100%; min-width: unset; diff --git a/packages/gantt/src/gantt.component.ts b/packages/gantt/src/gantt.component.ts index cfa8d91f..31d5181d 100644 --- a/packages/gantt/src/gantt.component.ts +++ b/packages/gantt/src/gantt.component.ts @@ -21,7 +21,7 @@ import { SimpleChanges } from '@angular/core'; import { startWith, takeUntil, take, finalize, skip } from 'rxjs/operators'; -import { Subject, Observable, from } from 'rxjs'; +import { Observable, from } from 'rxjs'; import { GanttUpper, GANTT_UPPER_TOKEN } from './gantt-upper'; import { GanttLinkDragEvent, GanttLineClickEvent, GanttItemInternal, GanttItem, GanttSelectedEvent, GanttGroupInternal } from './class'; import { NgxGanttTableColumnComponent } from './table/gantt-column.component'; @@ -75,8 +75,6 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, @ViewChild('ganttRoot') ganttRoot: NgxGanttRootComponent; - private ngUnsubscribe$ = new Subject(); - @ViewChild(CdkVirtualScrollViewport) virtualScroll: CdkVirtualScrollViewport; public flatData: (GanttGroupInternal | GanttItemInternal)[] = []; @@ -114,11 +112,11 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, this.computeTempDataRefs(); }); - this.dragContainer.linkDragStarted.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event: GanttLinkDragEvent) => { + this.dragContainer.linkDragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe((event: GanttLinkDragEvent) => { this.linkDragStarted.emit(event); }); - this.dragContainer.linkDragEnded.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((event: GanttLinkDragEvent) => { + this.dragContainer.linkDragEnded.pipe(takeUntil(this.unsubscribe$)).subscribe((event: GanttLinkDragEvent) => { this.linkDragEnded.emit(event); }); }); @@ -145,16 +143,7 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, } ngAfterViewInit() { - this.columns.changes.pipe(startWith(true), takeUntil(this.ngUnsubscribe$)).subscribe(() => { - this.columns.forEach((column) => { - if (!column.columnWidth) { - column.columnWidth = coerceCssPixelValue(defaultColumnWidth); - } - }); - this.cdr.detectChanges(); - }); - - this.virtualScroll.renderedRangeStream.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((range) => { + this.virtualScroll.renderedRangeStream.pipe(takeUntil(this.unsubscribe$)).subscribe((range) => { const linksElement = this.elementRef.nativeElement.querySelector('.gantt-links-overlay') as HTMLDivElement; linksElement.style.top = `${-(this.styles.lineHeight * range.start)}px`; this.rangeStart = range.start; @@ -203,22 +192,11 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, tempItemData.push(data); } }); - this.computeItemsRefs(...uniqBy(tempItemData, 'id')); this.flatData = [...this.flatData]; this.tempData = [...this.tempData]; } - private expandGroups(expanded: boolean) { - this.groups.forEach((group) => { - group.setExpand(expanded); - }); - - this.afterExpand(); - this.expandChange.next(null); - this.cdr.detectChanges(); - } - expandChildren(item: GanttItemInternal) { if (!item.expanded) { item.setExpand(true); @@ -275,18 +253,20 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, this.ganttRoot.scrollToDate(date); } - expandGroup(group: GanttGroupInternal) { - group.setExpand(!group.expanded); + override expandGroups(expanded: boolean) { + this.groups.forEach((group) => { + group.setExpand(expanded); + }); + this.afterExpand(); - this.expandChange.emit(); + this.expandChange.next(null); this.cdr.detectChanges(); } - expandAll() { - this.expandGroups(true); - } - - collapseAll() { - this.expandGroups(false); + override expandGroup(group: GanttGroupInternal) { + group.setExpand(!group.expanded); + this.afterExpand(); + this.expandChange.emit(); + this.cdr.detectChanges(); } } diff --git a/packages/gantt/src/table/test/table.spec.ts b/packages/gantt/src/table/test/table.spec.ts index bffb47dc..9b035e30 100644 --- a/packages/gantt/src/table/test/table.spec.ts +++ b/packages/gantt/src/table/test/table.spec.ts @@ -1,9 +1,9 @@ import { TestBed, ComponentFixture, async } from '@angular/core/testing'; import { Component, ViewChild, DebugElement } from '@angular/core'; import { NgxGanttModule } from 'ngx-gantt'; -import { GanttTableComponent } from '../../components/table/gantt-table.component'; import { getMockGroupItems, getMockGroups } from '../../test/mocks/data'; import { By } from '@angular/platform-browser'; +import { GanttTableBodyComponent } from '../../components/table/body/gantt-table-body.component'; @Component({ selector: 'test-gantt-table', @@ -21,7 +21,7 @@ import { By } from '@angular/platform-browser'; providers: [] }) export class TestGanttTableComponent { - @ViewChild(GanttTableComponent, { static: true }) ganttTableComponent: GanttTableComponent; + @ViewChild(GanttTableBodyComponent, { static: true }) ganttTableComponent: GanttTableBodyComponent; items = getMockGroupItems(); @@ -49,7 +49,7 @@ describe('NgxGanttTableComponent', () => { it('should create ngx-gantt-table', () => { expect(component).toBeDefined(); - const ganttTable: DebugElement = fixture.debugElement.query(By.directive(GanttTableComponent)); + const ganttTable: DebugElement = fixture.debugElement.query(By.directive(GanttTableBodyComponent)); expect(ganttTable).toBeTruthy(); expect(ganttTable.nativeElement).toBeTruthy(); });