Skip to content

Commit

Permalink
feat: support children display and async
Browse files Browse the repository at this point in the history
  • Loading branch information
walkerkay authored and HandsomeButterball committed Jun 23, 2020
1 parent ba7fe5b commit ca9faa0
Show file tree
Hide file tree
Showing 19 changed files with 219 additions and 81 deletions.
2 changes: 2 additions & 0 deletions example/src/app/examples/examples.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
[viewType]="options.viewType"
[draggable]="options.draggable"
[linkable]="options.linkable"
[async]="options.async"
[asyncChildrenResolve]="options.childrenResolve"
(barClick)="barClick($event)"
(lineClick)="lineClick($event)"
(dragEnded)="dragEnded($event)"
Expand Down
24 changes: 19 additions & 5 deletions example/src/app/examples/examples.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
GanttLineClickEvent,
GanttLinkDragEvent
} from 'ngx-gantt';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { GanttItem } from 'dist/gantt/class';

@Component({
selector: 'app-examples-gantt',
Expand All @@ -24,7 +27,9 @@ export class AppExamplesComponent implements OnInit {
options = {
viewType: GanttViewType.month,
draggable: true,
linkable: true
linkable: true,
async: true,
childrenResolve: this.getChildren.bind(this)
};

@HostBinding('class.gantt-demo') class = true;
Expand All @@ -39,10 +44,7 @@ export class AppExamplesComponent implements OnInit {
console.log(event);
}

dragEnded(event: GanttDragEvent) {
this.groups = [...this.groups];
this.items = [...this.items];
}
dragEnded(event: GanttDragEvent) {}

linkDragEnded(event: GanttLinkDragEvent) {
if (event.source.links && event.source.links.includes(event.target.id)) {
Expand All @@ -58,4 +60,16 @@ export class AppExamplesComponent implements OnInit {
}

loadOnScroll(event: GanttLoadOnScrollEvent) {}

getChildren(item: GanttItem) {
return of([
{
id: new Date().getTime(),
title: new Date().getTime(),
start: Math.floor(new Date().getTime() / 1000),
draggable: true,
linkable: false
}
]).pipe(delay(1000));
}
}
14 changes: 12 additions & 2 deletions example/src/app/examples/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,24 @@ export const mockItems = [
start: 1590035675,
group_id: '00001',
color: '#FF0000',
children: [
{
id: 'item-child-0101',
title: 'VERSION Children 0101',
start: 1590035675,
group_id: '00001',
color: '#FF0000',
linkable: false
}
]
},
{
id: 'item-0102',
title: 'VERSION 0102',
start: 1590935675,
end: 1591318400,
color: '#9ACD32',
group_id: '00001',
group_id: '00001'
},
{
id: 'item-0103',
Expand All @@ -46,7 +56,7 @@ export const mockItems = [
{
id: 'item-0201',
title: 'VERSION 0201',
group_id: '00002',
group_id: '00002'
},
{
id: 'item-0202',
Expand Down
14 changes: 13 additions & 1 deletion packages/gantt/src/class/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ export class GanttItemInternal {
end: GanttDate;
links: string[];
color?: string;
draggable?: boolean;
linkable?: boolean;
origin: GanttItem;
children: GanttItemInternal[];
expand: boolean;
loading: boolean;
children: GanttItemInternal[];

get refs() {
return this.refs$.getValue();
}
Expand All @@ -42,6 +46,8 @@ export class GanttItemInternal {
this.id = this.origin.id;
this.links = this.origin.links || [];
this.color = this.origin.color;
this.linkable = this.origin.linkable === undefined ? true : this.origin.linkable;
this.draggable = this.origin.draggable === undefined ? true : this.origin.draggable;
this.start = item.start ? new GanttDate(item.start) : null;
this.end = item.end ? new GanttDate(item.end) : null;
this.children = (item.children || []).map((subItem) => {
Expand All @@ -67,6 +73,12 @@ export class GanttItemInternal {
this.origin.end = this.end.getUnixTime();
}

addChildren(items: GanttItem[]) {
this.children = (items || []).map((subItem) => {
return new GanttItemInternal(subItem);
});
}

addLink(linkId: string) {
this.links = [...this.links, linkId];
this.origin.links = this.links;
Expand Down
12 changes: 7 additions & 5 deletions packages/gantt/src/components/bar/bar-drag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ export class GanttBarDrag implements OnDestroy {
private item: GanttItemInternal;

private get dragDisabled() {
return !this.ganttRef.draggable;
return !this.item.draggable || !this.ganttRef.draggable;
}

private get linkDragDisabled() {
return !this.ganttRef.linkable;
return !this.item.linkable || !this.ganttRef.linkable;
}

private linkDraggingLine: SVGElement;
Expand All @@ -49,8 +49,10 @@ export class GanttBarDrag implements OnDestroy {
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
if (this.dragContainer.linkDraggingId && this.dragContainer.linkDraggingId !== this.item.id) {
this.barElement.classList.add(linkDropClass);
this.dragContainer.emitLinkDragEntered(this.item);
if (this.item.linkable) {
this.barElement.classList.add(linkDropClass);
this.dragContainer.emitLinkDragEntered(this.item);
}
} else {
this.barElement.classList.add(activeClass);
}
Expand Down Expand Up @@ -271,7 +273,7 @@ export class GanttBarDrag implements OnDestroy {
this.barElement = elementRef.nativeElement;
this.ganttRef = ganttRef;

if (this.dragDisabled && this.linkDragDisabled) {
if (!item.draggable || (this.dragDisabled && this.linkDragDisabled)) {
return;
} else {
this.createMouseEvents();
Expand Down
4 changes: 2 additions & 2 deletions packages/gantt/src/components/bar/bar.component.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<div class="gantt-bar-layer">
<div *ngIf="ganttRef.draggable" class="drag-handles">
<div *ngIf="item.draggable && ganttRef.draggable" class="drag-handles">
<ng-container>
<span class="handle"></span>
<span class="handle"></span>
</ng-container>
</div>
<div *ngIf="ganttRef.linkable" class="link-handles">
<div *ngIf="item.linkable && ganttRef.linkable" class="link-handles">
<span class="handle"><span class="point"></span></span>
<span class="handle"> <span class="point"></span></span>
</div>
Expand Down
8 changes: 7 additions & 1 deletion packages/gantt/src/components/icon/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ const angleRight = `<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"
const angleDown = `<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false"><g id="aknavigation/angle-down" stroke-width="1" fill-rule="evenodd"><path d="M7.978 11.997l-.005.006L2.3 6.33l.83-.831 4.848 4.848L12.826 5.5l.83.83-5.673 5.673-.005-.006z" ></path></g></svg>`;
const plusSquare = `<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false"><g id="kxaction/plus-square" stroke-width="1" fill-rule="evenodd"><path d="M2 0h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm0 1.2a.8.8 0 0 0-.8.8v12a.8.8 0 0 0 .8.8h12a.8.8 0 0 0 .8-.8V2a.8.8 0 0 0-.8-.8H2zm5.45 6.2V4.75h1.2V7.4h2.65v1.2H8.65v2.65h-1.2V8.6H4.8V7.4h2.65z"></path></g></svg>`;
const minusSquare = `<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false"><g id="jnaction/minus-square" stroke-width="1" fill-rule="evenodd"><path d="M2 0h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm0 1.2a.8.8 0 0 0-.8.8v12a.8.8 0 0 0 .8.8h12a.8.8 0 0 0 .8-.8V2a.8.8 0 0 0-.8-.8H2zm2.8 6.2h6.5v1.2H4.8V7.4z"></path></g></svg>`;
const loadingIcon = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50" xml:space="preserve">
<path fill="#888" d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" transform="rotate(275.098 25 25)">
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="0.6s" repeatCount="indefinite"></animateTransform>
</path>
</svg>`;
export const icons = {
'angle-right': angleRight,
'angle-down': angleDown,
'plus-square': plusSquare,
'minus-square': minusSquare
'minus-square': minusSquare,
loading: loadingIcon
};
27 changes: 19 additions & 8 deletions packages/gantt/src/components/links/links.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ import {
Inject,
ChangeDetectorRef,
ElementRef,
OnDestroy
OnDestroy,
OnChanges
} from '@angular/core';
import { merge, Subject } from 'rxjs';
import { takeUntil, skip } from 'rxjs/operators';
import { GanttGroupInternal } from '../../class/group';
import { GanttItemInternal, GanttItem } from './../../class/item';
import { GanttLineClickEvent } from '../../class/event';
import { GANTT_REF_TOKEN, GanttRef } from '../../gantt-ref';
import { GanttDragContainer } from '../../gantt-drag-container';
import { merge, Subject } from 'rxjs';
import { takeUntil, skip } from 'rxjs/operators';
import { recursiveItems } from '../../utils/helpers';

enum LinkColors {
default = '#cacaca',
Expand All @@ -43,7 +45,7 @@ interface LinkInternal {
selector: 'gantt-links-overlay',
templateUrl: './links.component.html'
})
export class GanttLinksComponent implements OnInit, OnDestroy {
export class GanttLinksComponent implements OnInit, OnChanges, OnDestroy {
@Input() groups: GanttGroupInternal[] = [];

@Input() items: GanttItemInternal[] = [];
Expand Down Expand Up @@ -72,11 +74,18 @@ export class GanttLinksComponent implements OnInit, OnDestroy {
ngOnInit() {
this.buildLinks();
this.firstChange = false;

this.ganttDragContainer.dragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
this.elementRef.nativeElement.style.visibility = 'hidden';
});

merge(this.ganttDragContainer.dragEnded, this.ganttDragContainer.linkDragEnded, this.gantt.view.start$, this.gantt.groupExpand$)
merge(
this.gantt.viewChange,
this.gantt.expandChange,
this.gantt.view.start$,
this.ganttDragContainer.dragEnded,
this.ganttDragContainer.linkDragEnded
)
.pipe(takeUntil(this.unsubscribe$), skip(1))
.subscribe(() => {
this.elementRef.nativeElement.style.visibility = 'visible';
Expand All @@ -101,7 +110,8 @@ export class GanttLinksComponent implements OnInit, OnDestroy {
this.groups.forEach((group) => {
groupNum++;
if (group.expand) {
group.items.forEach((item, itemIndex) => {
const items = recursiveItems(group.items);
items.forEach((item, itemIndex) => {
const y = (groupNum + itemNum + itemIndex) * lineHeight + item.refs.y + barHeight / 2;
this.linkItems.push({
...item,
Expand All @@ -115,11 +125,12 @@ export class GanttLinksComponent implements OnInit, OnDestroy {
}
});
});
itemNum += group.items.length;
itemNum += items.length;
}
});
} else {
this.items.forEach((item, itemIndex) => {
const items = recursiveItems(this.items);
items.forEach((item, itemIndex) => {
const y = itemIndex * lineHeight + item.refs.y + barHeight / 2;
this.linkItems.push({
...item,
Expand Down
8 changes: 5 additions & 3 deletions packages/gantt/src/components/main/gantt-main.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
<div class="gantt-item" [style.height.px]="ganttRef.styles.lineHeight">
<gantt-bar [item]="item" [template]="barTemplate" (barClick)="barClick.emit($event)"></gantt-bar>
</div>
<ng-container *ngFor="let item of item.children; trackBy: trackBy">
<ng-template [ngTemplateOutlet]="ganttItems" [ngTemplateOutletContext]="{ items: item.children }"></ng-template>
</ng-container>
<ng-template
*ngIf="item.children && item.expand"
[ngTemplateOutlet]="ganttItems"
[ngTemplateOutletContext]="{ items: item.children }"
></ng-template>
</ng-container>
</ng-template>
2 changes: 0 additions & 2 deletions packages/gantt/src/components/main/gantt-main.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ export class GanttMainComponent implements OnInit {

@Output() lineClick = new EventEmitter<GanttLineClickEvent>();

@ViewChild(GanttLinksComponent, { static: false, }) links: GanttLinksComponent;

@HostBinding('class.gantt-main-container') ganttMainClass = true;

constructor(@Inject(GANTT_REF_TOKEN) public ganttRef: GanttRef) {}
Expand Down
34 changes: 25 additions & 9 deletions packages/gantt/src/components/table/gantt-table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,46 @@
</div>

<ng-container *ngIf="group.expand">
<ng-template [ngTemplateOutlet]="ganttItems" [ngTemplateOutletContext]="{ items: group.items }"></ng-template>
<ng-template [ngTemplateOutlet]="ganttItems" [ngTemplateOutletContext]="{ items: group.items, level: 0 }"></ng-template>
</ng-container>
</ng-container>
</ng-container>
</div>
</div>

<ng-template #itemsTemplate>
<ng-template [ngTemplateOutlet]="ganttItems" [ngTemplateOutletContext]="{ items: items }"></ng-template>
<ng-template [ngTemplateOutlet]="ganttItems" [ngTemplateOutletContext]="{ items: items, level: 0 }"></ng-template>
</ng-template>

<ng-template #ganttItems let-items="items">
<ng-template #ganttItems let-items="items" let-level="level">
<ng-container *ngFor="let item of items">
<div class="gantt-table-item gantt-table-row" [style.height.px]="ganttRef.styles.lineHeight" [style.lineHeight.px]="ganttRef.styles.lineHeight">
<div class="item-column gantt-table-column" *ngFor="let column of columnList" [style.width.px]="column.width">
<div
class="gantt-table-item gantt-table-row"
[style.height.px]="ganttRef.styles.lineHeight"
[style.lineHeight.px]="ganttRef.styles.lineHeight"
>
<div class="item-column gantt-table-column" *ngFor="let column of columnList; let first = first" [style.width.px]="column.width">
<div *ngIf="first" class="gantt-expand-icon" [style.marginLeft.px]="level * 20">
<ng-container *ngIf="level < ganttRef.maxLevel - 1">
<gantt-icon
*ngIf="!item.loading"
class="expand-icon"
[iconName]="item.expand ? 'angle-down' : 'angle-right'"
(click)="expandChildren(item)"
></gantt-icon>
<gantt-icon *ngIf="item.loading" [iconName]="'loading'"></gantt-icon>
</ng-container>
</div>
<ng-template
[ngTemplateOutlet]="column.templateRef"
[ngTemplateOutletContext]="{ $implicit: item.origin, item: item.origin }"
></ng-template>
</div>
</div>

<ng-container *ngFor="let item of item.children">
<ng-template [ngTemplateOutlet]="ganttItems" [ngTemplateOutletContext]="{ items: item.children }"></ng-template>
</ng-container>
<ng-template
*ngIf="item.children && item.expand"
[ngTemplateOutlet]="ganttItems"
[ngTemplateOutletContext]="{ items: item.children, level: level + 1 }"
></ng-template>
</ng-container>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,10 @@
background-color: $gantt-container-background-color;
}
}

.gantt-expand-icon {
display: inline-block;
width: 16px;
}
}
}
12 changes: 7 additions & 5 deletions packages/gantt/src/components/table/gantt-table.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, HostBinding, TemplateRef, QueryList, Input, OnInit, Inject, ElementRef, Output, EventEmitter } from '@angular/core';
import { GanttItemInternal, GanttGroupInternal } from '../../class';
import { GanttItemInternal, GanttGroupInternal, GanttItem } from '../../class';
import { GANTT_REF_TOKEN, GanttRef } from '../../gantt-ref';
import { NgxGanttTableColumnComponent } from '../../table/gantt-column.component';

Expand All @@ -23,13 +23,15 @@ export class GanttTableComponent implements OnInit {

@HostBinding('class.gantt-table') ganttTableClass = true;

constructor(@Inject(GANTT_REF_TOKEN) public ganttRef: GanttRef, private elementRef: ElementRef) {}
constructor(@Inject(GANTT_REF_TOKEN) public ganttRef: GanttRef) {}

ngOnInit() {}

expandGroup(group: GanttGroupInternal) {
group.expand = !group.expand;
this.ganttRef.groupExpand$.next();
this.ganttRef.detectChanges();
this.ganttRef.expandGroup(group);
}

expandChildren(item: GanttItemInternal) {
this.ganttRef.expandChildren(item);
}
}
Loading

0 comments on commit ca9faa0

Please sign in to comment.