From 65aa1f31112df8358d2cbbc0a1774db7bcfa86be Mon Sep 17 00:00:00 2001 From: zhangwen <1062680993@qq.com> Date: Wed, 16 Aug 2023 17:40:29 +0800 Subject: [PATCH] feat: merge v15.2.0-next --- .wpmrc.js | 2 +- CHANGELOG.md | 12 ++++ docs/guides/basic/event.md | 15 +++++ .../app/configuration/parameters/api/zh-cn.js | 23 ++++++-- .../app/gantt-custom-view/gantt.component.ts | 6 +- .../gantt-virtual-scroll/gantt.component.html | 46 ++++++++++++--- .../gantt-virtual-scroll/gantt.component.ts | 30 ++++++++-- example/src/app/gantt/gantt.component.html | 3 - example/src/app/gantt/gantt.component.ts | 1 + example/src/app/gantt/gantt.scss | 0 example/src/app/helper.ts | 2 +- example/src/styles.scss | 27 +++++++++ packages/gantt/src/class/event.ts | 9 +++ packages/gantt/src/gantt-dom.service.ts | 49 ++++++++++++---- packages/gantt/src/gantt.component.html | 33 ++++++++++- packages/gantt/src/gantt.component.scss | 58 ++++++++++++++++++- packages/gantt/src/gantt.component.ts | 39 +++++++++---- packages/gantt/src/styles/variables.scss | 3 + .../gantt/src/table/gantt-table.component.ts | 4 ++ 19 files changed, 311 insertions(+), 51 deletions(-) create mode 100644 example/src/app/gantt/gantt.scss diff --git a/.wpmrc.js b/.wpmrc.js index 83472243..81218936 100644 --- a/.wpmrc.js +++ b/.wpmrc.js @@ -1,5 +1,5 @@ module.exports = { - allowBranch: ['master', 'release-auto-*'], + allowBranch: ['master', 'v15.*', 'v16.*', 'v17.*', 'release-auto-*'], bumpFiles: ['package.json', 'package-lock.json', 'packages/gantt/package.json'], skip: { confirm: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 652f2bab..1c7c9575 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,18 @@ All notable changes to this project will be documented in this file. See [standa - fix children display error when dropEnterPredicate return false #INFR-8641 ([54c3455](https://github.com/worktile/ngx-gantt/commit/54c3455739e0e6559e18f0e77130c84a50e5e118)), closes [#INFR-8641](https://github.com/worktile/ngx-gantt/issues/INFR-8641) +# [15.2.0-next.1](https://github.com/worktile/ngx-gantt/compare/15.2.0-next.0...15.2.0-next.1) (2023-07-28) + +### Features + +- support load data when virtual scroll #INFR-8652 ([#395](https://github.com/worktile/ngx-gantt/issues/395)) ([f20ad4c](https://github.com/worktile/ngx-gantt/commit/f20ad4c3913b0fe7a19ae480dec495a99392427a)), closes [#INFR-8652](https://github.com/worktile/ngx-gantt/issues/INFR-8652) [#INFR-8626](https://github.com/worktile/ngx-gantt/issues/INFR-8626) + +# [15.2.0-next.0](https://github.com/worktile/ngx-gantt/compare/15.1.1...15.2.0-next.0) (2023-07-19) + +### Features + +- gantt component support footer template #INFR-8626 ([#394](https://github.com/worktile/ngx-gantt/issues/394)) ([c437b0c](https://github.com/worktile/ngx-gantt/commit/c437b0c80782ce1c17e38d63eaf49c76554ca3b3)), closes [#INFR-8626](https://github.com/worktile/ngx-gantt/issues/INFR-8626) [#INFR-8626](https://github.com/worktile/ngx-gantt/issues/INFR-8626) + ## [15.1.1](https://github.com/worktile/ngx-gantt/compare/15.1.0...15.1.1) (2023-07-05) ### Bug Fixes diff --git a/docs/guides/basic/event.md b/docs/guides/basic/event.md index c3e6b0c0..97a61806 100644 --- a/docs/guides/basic/event.md +++ b/docs/guides/basic/event.md @@ -115,3 +115,18 @@ export class GanttTableDragEndedEvent { sourceParent: GanttItem; // 拖动开始数据项父 } ``` + +# GanttVirtualScrolledIndexChangeEvent + +Gantt 组件虚拟滚动视口中可见的第一个元素的索引发生变化时触发 + +```ts +export class GanttVirtualScrolledIndexChangeEvent { + index: number; // 视口第一个元素 index + renderedRange: { + start: number; + end: number; + }; // 当前渲染的条目范围 + count: number; // 总条目数量 +} +``` diff --git a/example/src/app/configuration/parameters/api/zh-cn.js b/example/src/app/configuration/parameters/api/zh-cn.js index dbb6b825..69ba26f5 100644 --- a/example/src/app/configuration/parameters/api/zh-cn.js +++ b/example/src/app/configuration/parameters/api/zh-cn.js @@ -169,6 +169,11 @@ module.exports = [ description: `选择数据项事件`, type: 'EventEmitter' }, + { + name: 'virtualScrolledIndexChange', + description: `虚拟滚动视口中可见的第一个元素的索引发生变化事件`, + type: 'EventEmitter' + }, { name: '#group', description: `设置分组显示模板`, @@ -185,13 +190,13 @@ module.exports = [ type: 'TemplateRef' }, { - name: '#tableEmpty', - description: `设置空表格模板`, + name: '#toolbar', + description: `工具栏自定义模版`, type: 'TemplateRef' }, { - name: '#toolbar', - description: `工具栏自定义模版`, + name: '#tableFooter', + description: `设置底部模板`, type: 'TemplateRef' } ] @@ -246,6 +251,16 @@ module.exports = [ name: '#rowAfterSlot', description: `设置表格中每行的后置自定义渲染模板`, type: 'TemplateRef' + }, + { + name: '#tableEmpty', + description: `设置空表格模板`, + type: 'TemplateRef' + }, + { + name: '#tableFooter', + description: `设置表格底部模板`, + type: 'TemplateRef' } ] }, diff --git a/example/src/app/gantt-custom-view/gantt.component.ts b/example/src/app/gantt-custom-view/gantt.component.ts index 65af0c7c..258141b0 100644 --- a/example/src/app/gantt-custom-view/gantt.component.ts +++ b/example/src/app/gantt-custom-view/gantt.component.ts @@ -23,7 +23,7 @@ registerView(customViewType, GanttViewCustom); selector: 'app-gantt-custom-view-example', templateUrl: './gantt.component.html' }) -export class AppGanttCustomViewExampleComponent implements OnInit, AfterViewInit { +export class AppGanttCustomViewExampleComponent implements OnInit { viewType = customViewType; showWeekend = true; @@ -78,10 +78,6 @@ export class AppGanttCustomViewExampleComponent implements OnInit, AfterViewInit ngOnInit(): void {} - ngAfterViewInit() { - setTimeout(() => this.ganttComponent.scrollToDate(1627729997), 200); - } - barClick(event: GanttBarClickEvent) { this.thyNotify.info('Event: barClick', `你点击了 [${event.item.title}]`); } diff --git a/example/src/app/gantt-virtual-scroll/gantt.component.html b/example/src/app/gantt-virtual-scroll/gantt.component.html index bf2653e4..00513b66 100644 --- a/example/src/app/gantt-virtual-scroll/gantt.component.html +++ b/example/src/app/gantt-virtual-scroll/gantt.component.html @@ -1,12 +1,18 @@ -
-
- NgxGantt - 默认开启了虚拟滚动功能,如需关闭该功能设置 virtualScrollEnabled 参数为 false 即可。 -
-
+ + + NgxGantt +   默认开启了虚拟滚动功能,如需关闭该功能设置 virtualScrollEnabled 参数为 false 即可。 + + - + {{ item.title }} @@ -21,11 +27,37 @@ {{ item.end * 1000 | date : 'yyyy-MM-dd' }} + + + +   {{ item.title }} + + + + diff --git a/example/src/app/gantt-virtual-scroll/gantt.component.ts b/example/src/app/gantt-virtual-scroll/gantt.component.ts index c989ccf0..85bb3217 100644 --- a/example/src/app/gantt-virtual-scroll/gantt.component.ts +++ b/example/src/app/gantt-virtual-scroll/gantt.component.ts @@ -1,5 +1,6 @@ -import { Component, OnInit, HostBinding, ViewChild, AfterViewInit } from '@angular/core'; -import { GanttItem, GanttPrintService, NgxGanttComponent } from 'ngx-gantt'; +import { Component, OnInit, HostBinding, ViewChild, AfterViewInit, ChangeDetectorRef } from '@angular/core'; +import { GanttItem, GanttPrintService, GanttVirtualScrolledIndexChangeEvent, NgxGanttComponent } from 'ngx-gantt'; +import { delay, of } from 'rxjs'; import { randomItems, random } from '../helper'; @Component({ @@ -8,13 +9,15 @@ import { randomItems, random } from '../helper'; providers: [GanttPrintService] }) export class AppGanttVirtualScrollExampleComponent implements OnInit, AfterViewInit { - items: GanttItem[] = randomItems(10000); + items: GanttItem[] = []; @HostBinding('class.gantt-example-component') class = true; @ViewChild('gantt') ganttComponent: NgxGanttComponent; - constructor() {} + loading = false; + + constructor(private cdr: ChangeDetectorRef) {} ngOnInit(): void { // init items children @@ -28,4 +31,23 @@ export class AppGanttVirtualScrollExampleComponent implements OnInit, AfterViewI ngAfterViewInit() { setTimeout(() => this.ganttComponent.scrollToDate(1627729997), 200); } + + virtualScrolledIndexChange(event: GanttVirtualScrolledIndexChangeEvent) { + // 检查滚动位置是否接近列表底部 + if (event.renderedRange.end + 20 >= event.count) { + // 加载更多数据 + if (!this.loading) { + const items = randomItems(100); + this.loading = true; + of(items) + .pipe(delay(1000)) + .subscribe(() => { + console.log('loadDone'); + this.loading = false; + this.items = [...this.items, ...items]; + this.cdr.detectChanges(); + }); + } + } + } } diff --git a/example/src/app/gantt/gantt.component.html b/example/src/app/gantt/gantt.component.html index cbb4d052..b55896f3 100644 --- a/example/src/app/gantt/gantt.component.html +++ b/example/src/app/gantt/gantt.component.html @@ -76,9 +76,6 @@   {{ item.title }} - diff --git a/example/src/app/gantt/gantt.component.ts b/example/src/app/gantt/gantt.component.ts index 9c955496..24c4130a 100644 --- a/example/src/app/gantt/gantt.component.ts +++ b/example/src/app/gantt/gantt.component.ts @@ -25,6 +25,7 @@ import { randomItems, random } from '../helper'; @Component({ selector: 'app-gantt-example', templateUrl: './gantt.component.html', + styleUrls: ['./gantt.scss'], providers: [GanttPrintService] }) export class AppGanttExampleComponent implements OnInit, AfterViewInit { diff --git a/example/src/app/gantt/gantt.scss b/example/src/app/gantt/gantt.scss new file mode 100644 index 00000000..e69de29b diff --git a/example/src/app/helper.ts b/example/src/app/helper.ts index 18163996..b653d888 100644 --- a/example/src/app/helper.ts +++ b/example/src/app/helper.ts @@ -11,7 +11,7 @@ export function randomItems(length: number, parent?: GanttItem, group?: string) const start = addDays(new Date(), random(-200, 200)); const end = addDays(start, random(0, 100)); items.push({ - id: `${parent?.id || group || ''}00000${i}`, + id: `${parent?.id || group || ''}${Math.floor(Math.random() * 100000000)}`, title: `${parent?.title || 'Task'}-${i}`, start: getUnixTime(start), end: getUnixTime(end), diff --git a/example/src/styles.scss b/example/src/styles.scss index d953bdc4..fc20c07b 100644 --- a/example/src/styles.scss +++ b/example/src/styles.scss @@ -45,6 +45,7 @@ $primary: #6698ff; margin: 20px; border: 1px solid #eee; height: calc(100vh - 95px); + overflow: auto; .thy-layout-header { .layout-header-title { @@ -62,6 +63,32 @@ $primary: #6698ff; } ngx-gantt-root { border: 1px solid #eee; + .table-footer { + display: flex; + .gantt-table-column { + overflow: hidden; + border-right: 1px solid #eee; + box-sizing: border-box; + padding: 0 15px; + line-height: 44px; + + &:last-child { + border-right: none; + } + } + } + .footer-container { + display: flex; + position: relative; + height: 100%; + .footer-item { + border-right: 1px solid #eee; + line-height: 44px; + &:last-child { + border-right: none; + } + } + } } } } diff --git a/packages/gantt/src/class/event.ts b/packages/gantt/src/class/event.ts index d71c8483..0066dbd9 100644 --- a/packages/gantt/src/class/event.ts +++ b/packages/gantt/src/class/event.ts @@ -63,3 +63,12 @@ export class GanttTableDragEnterPredicateContext { target: GanttItem; dropPosition: GanttTableDropPosition; } + +export class GanttVirtualScrolledIndexChangeEvent { + index: number; + renderedRange: { + start: number; + end: number; + }; + count: number; +} diff --git a/packages/gantt/src/gantt-dom.service.ts b/packages/gantt/src/gantt-dom.service.ts index 783aff74..6e1b26bc 100644 --- a/packages/gantt/src/gantt-dom.service.ts +++ b/packages/gantt/src/gantt-dom.service.ts @@ -40,16 +40,25 @@ export class GanttDomService implements OnDestroy { public linksOverlay: Element; + private mainFooter: Element; + + private mainScrollbar: Element; + private unsubscribe$ = new Subject(); constructor(private ngZone: NgZone, @Inject(PLATFORM_ID) private platformId: string) {} private monitorScrollChange() { + const scrollObservers = [ + fromEvent(this.mainContainer, 'scroll', passiveListenerOptions), + fromEvent(this.sideContainer, 'scroll', passiveListenerOptions) + ]; + + this.mainFooter && scrollObservers.push(fromEvent(this.mainFooter, 'scroll', passiveListenerOptions)); + this.mainScrollbar && scrollObservers.push(fromEvent(this.mainScrollbar, 'scroll', passiveListenerOptions)); + this.ngZone.runOutsideAngular(() => - merge( - fromEvent(this.mainContainer, 'scroll', passiveListenerOptions), - fromEvent(this.sideContainer, 'scroll', passiveListenerOptions) - ) + merge(...scrollObservers) .pipe(takeUntil(this.unsubscribe$)) .subscribe((event) => { this.syncScroll(event); @@ -59,11 +68,22 @@ export class GanttDomService implements OnDestroy { private syncScroll(event: Event) { const target = event.currentTarget as HTMLElement; - this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft; - this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft; - - this.sideContainer.scrollTop = target.scrollTop; - this.mainContainer.scrollTop = target.scrollTop; + const classList = target.classList; + + if (!classList.contains('gantt-side-container')) { + this.mainContainer.scrollLeft = target.scrollLeft; + this.calendarHeader.scrollLeft = target.scrollLeft; + this.calendarOverlay.scrollLeft = target.scrollLeft; + this.mainScrollbar && (this.mainScrollbar.scrollLeft = target.scrollLeft); + this.mainFooter && (this.mainFooter.scrollLeft = target.scrollLeft); + if (classList.contains('gantt-main-container')) { + this.sideContainer.scrollTop = target.scrollTop; + this.mainContainer.scrollTop = target.scrollTop; + } + } else { + this.sideContainer.scrollTop = target.scrollTop; + this.mainContainer.scrollTop = target.scrollTop; + } } private disableBrowserWheelEvent() { @@ -92,10 +112,11 @@ export class GanttDomService implements OnDestroy { this.container = this.root.getElementsByClassName('gantt-container')[0]; this.sideContainer = this.root.getElementsByClassName('gantt-side-container')[0]; this.mainContainer = this.root.getElementsByClassName('gantt-main-container')[0]; + this.mainScrollbar = this.root.getElementsByClassName('gantt-main-scrollbar')[0]; + this.mainFooter = this.root.getElementsByClassName('gantt-container-footer')[0]; this.verticalScrollContainer = this.root.getElementsByClassName('gantt-scroll-container')[0]; const mainItems = this.mainContainer.getElementsByClassName('gantt-main-items')[0]; const mainGroups = this.mainContainer.getElementsByClassName('gantt-main-groups')[0]; - this.mainItems = mainItems || mainGroups; this.calendarHeader = this.root.getElementsByClassName('gantt-calendar-header')[0]; this.calendarOverlay = this.root.getElementsByClassName('gantt-calendar-grid')[0]; @@ -109,9 +130,13 @@ export class GanttDomService implements OnDestroy { * to run the change detection if needed. */ getViewerScroll(options?: AddEventListenerOptions): Observable { + const scrollObservers = [fromEvent(this.mainContainer, 'scroll', options)]; + this.mainFooter && scrollObservers.push(fromEvent(this.mainFooter, 'scroll', options)); + this.mainScrollbar && scrollObservers.push(fromEvent(this.mainScrollbar, 'scroll', options)); + return new Observable((subscriber) => this.ngZone.runOutsideAngular(() => - fromEvent(this.mainContainer, 'scroll', options) + merge(...scrollObservers) .pipe( map(() => this.mainContainer.scrollLeft), pairwise(), @@ -151,6 +176,8 @@ export class GanttDomService implements OnDestroy { this.mainContainer.scrollLeft = scrollLeft > scrollThreshold ? scrollLeft : 0; this.calendarHeader.scrollLeft = this.mainContainer.scrollLeft; this.calendarOverlay.scrollLeft = this.mainContainer.scrollLeft; + this.mainScrollbar && (this.mainScrollbar.scrollLeft = this.mainContainer.scrollLeft); + this.mainFooter && (this.mainFooter.scrollLeft = this.mainContainer.scrollLeft); } } diff --git a/packages/gantt/src/gantt.component.html b/packages/gantt/src/gantt.component.html index d52c5bd0..4dbb822e 100644 --- a/packages/gantt/src/gantt.component.html +++ b/packages/gantt/src/gantt.component.html @@ -9,10 +9,15 @@
@@ -23,7 +28,7 @@ [viewportItems]="viewportItems" [columns]="columns" [groupTemplate]="groupTemplate" - [emptyTemplate]="tableEmptyTemplate" + [emptyTemplate]="table.tableEmptyTemplate || tableEmptyTemplate" [rowBeforeTemplate]="table?.rowBeforeTemplate" [rowAfterTemplate]="table?.rowAfterTemplate" [draggable]="table.draggable" @@ -59,4 +64,28 @@ + +
+
+
+
+
+
+ + diff --git a/packages/gantt/src/gantt.component.scss b/packages/gantt/src/gantt.component.scss index 6f5c0d8c..66a382d9 100644 --- a/packages/gantt/src/gantt.component.scss +++ b/packages/gantt/src/gantt.component.scss @@ -18,7 +18,6 @@ border-right: 1px solid variables.$gantt-border-color; position: relative; z-index: 3; - // overflow-x: scroll; box-shadow: variables.$gantt-side-shadow; .gantt-side-header { @@ -49,6 +48,25 @@ background-color: variables.$gantt-container-background-color; } + .gantt-scrollbar { + position: absolute; + left: 0; + bottom: 0; + right: 0; + z-index: 3; + display: flex; + .gantt-table-scrollbar { + &.with-scrollbar { + overflow-x: scroll; + } + } + .gantt-main-scrollbar { + flex: 1; + overflow-x: auto; + overflow-y: hidden; + } + } + .gantt-main-container { width: 100%; height: calc(100% - #{variables.$gantt-header-height}); @@ -58,7 +76,6 @@ bottom: 0; left: 0; right: 0; - // 兼容火狐浏览器 overflow: auto; background-color: variables.$gantt-container-background-color; @@ -97,8 +114,17 @@ right: 0; bottom: 0; z-index: 2; - // 兼容火狐浏览器 overflow: auto; + + &.with-footer { + .gantt-table-body { + padding-bottom: variables.$gantt-footer-height; + } + .gantt-main-groups, + .gantt-main-items { + padding-bottom: variables.$gantt-footer-height; + } + } .cdk-virtual-scroll-content-wrapper { width: 100%; min-width: unset; @@ -139,3 +165,29 @@ background-color: #fafafa; } } + +.gantt-footer { + display: flex; + position: absolute; + left: 0; + right: 0; + bottom: 0; + z-index: 2; + background-color: white; + border-top: 1px solid variables.$gantt-border-color; + + .gantt-table-footer { + height: variables.$gantt-footer-height; + border-right: 1px solid variables.$gantt-border-color; + box-shadow: variables.$gantt-side-shadow; + } + .gantt-container-footer { + height: variables.$gantt-footer-height; + overflow-x: auto; + overflow-y: hidden; + flex: 1; + &::-webkit-scrollbar { + display: none; + } + } +} diff --git a/packages/gantt/src/gantt.component.ts b/packages/gantt/src/gantt.component.ts index 39648bdb..0d990b81 100644 --- a/packages/gantt/src/gantt.component.ts +++ b/packages/gantt/src/gantt.component.ts @@ -23,7 +23,15 @@ import { import { takeUntil, take, finalize, skip } from 'rxjs/operators'; import { Observable, from } from 'rxjs'; import { GanttUpper, GANTT_UPPER_TOKEN } from './gantt-upper'; -import { GanttLinkDragEvent, GanttLineClickEvent, GanttItemInternal, GanttItem, GanttSelectedEvent, GanttGroupInternal } from './class'; +import { + GanttLinkDragEvent, + GanttLineClickEvent, + GanttItemInternal, + GanttItem, + GanttSelectedEvent, + GanttGroupInternal, + GanttVirtualScrolledIndexChangeEvent +} from './class'; import { NgxGanttTableColumnComponent } from './table/gantt-column.component'; import { NgxGanttTableComponent } from './table/gantt-table.component'; import { GANTT_ABSTRACT_TOKEN } from './gantt-abstract'; @@ -32,7 +40,6 @@ import { NgxGanttRootComponent } from './root.component'; import { GanttDate } from './utils/date'; import { CdkVirtualScrollViewport, ViewportRuler } from '@angular/cdk/scrolling'; import { Dictionary, keyBy, recursiveItems, uniqBy } from './utils/helpers'; - @Component({ selector: 'ngx-gantt', templateUrl: './gantt.component.html', @@ -75,7 +82,7 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, @Input() virtualScrollEnabled = true; - @Input() loadingDelay: number = 0; + @Input() loadingDelay = 0; @Output() linkDragStarted = new EventEmitter(); @@ -85,14 +92,19 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, @Output() selectedChange = new EventEmitter(); + @Output() virtualScrolledIndexChange = new EventEmitter(); + @ContentChild(NgxGanttTableComponent) override table: NgxGanttTableComponent; @ContentChildren(NgxGanttTableColumnComponent, { descendants: true }) columns: QueryList; + // 此模版已挪到 table 组件下,为了兼容此处暂时保留 @ContentChild('tableEmpty', { static: true }) tableEmptyTemplate: TemplateRef; @ViewChild('ganttRoot') ganttRoot: NgxGanttRootComponent; + @ContentChild('footer', { static: true }) footerTemplate: TemplateRef; + @ViewChild(CdkVirtualScrollViewport) virtualScroll: CdkVirtualScrollViewport; get loading() { @@ -107,9 +119,9 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, private loadingTimer; - private rangeStart: number; + private rangeStart = 0; - private rangeEnd: number; + private rangeEnd = 0; private flatItemsMap: Dictionary; @@ -134,10 +146,6 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, // using `zone-patch-rxjs` because it'll trigger a change detection when it unsubscribes. this.ngZone.runOutsideAngular(() => { onStable$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { - // this.dragContainer.dragEnded.subscribe((event) => { - // this.computeTempDataRefs(); - // }); - this.dragContainer.linkDragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe((event: GanttLinkDragEvent) => { this.linkDragStarted.emit(event); }); @@ -219,7 +227,7 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, this.flatItemsMap = keyBy(this.flatItems, 'id'); if (!this.virtualScrollEnabled) { this.rangeStart = 0; - this.rangeEnd = this.flatItems.length - 1; + this.rangeEnd = this.flatItems.length; } } @@ -304,6 +312,17 @@ export class NgxGanttComponent extends GanttUpper implements OnInit, OnChanges, this.ganttRoot.scrollToDate(date); } + scrolledIndexChange(index: number) { + this.virtualScrolledIndexChange.emit({ + index, + renderedRange: { + start: this.rangeStart, + end: this.rangeEnd + }, + count: this.flatItems.length + }); + } + override expandGroups(expanded: boolean) { this.groups.forEach((group) => { group.setExpand(expanded); diff --git a/packages/gantt/src/styles/variables.scss b/packages/gantt/src/styles/variables.scss index e300b664..235b7224 100644 --- a/packages/gantt/src/styles/variables.scss +++ b/packages/gantt/src/styles/variables.scss @@ -56,3 +56,6 @@ $gantt-toolbar-view-active-color: $gantt-primary-color !default; // loader $gantt-loader-loading-color: $gantt-primary-color !default; + +// footer +$gantt-footer-height: 44px !default; diff --git a/packages/gantt/src/table/gantt-table.component.ts b/packages/gantt/src/table/gantt-table.component.ts index 47a7393f..d7cde7a1 100644 --- a/packages/gantt/src/table/gantt-table.component.ts +++ b/packages/gantt/src/table/gantt-table.component.ts @@ -27,4 +27,8 @@ export class NgxGanttTableComponent { @ContentChild('rowBeforeSlot', { static: true }) rowBeforeTemplate: TemplateRef; @ContentChild('rowAfterSlot', { static: true }) rowAfterTemplate: TemplateRef; + + @ContentChild('tableEmpty', { static: true }) tableEmptyTemplate: TemplateRef; + + @ContentChild('tableFooter', { static: true }) tableFooterTemplate: TemplateRef; }