diff --git a/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.html b/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.html new file mode 100644 index 0000000..3cae2a0 --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.html @@ -0,0 +1,12 @@ +
+ + +
diff --git a/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.scss b/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.scss new file mode 100644 index 0000000..f43bcb2 --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.scss @@ -0,0 +1,4 @@ +.gantt-scroll-icon { + height: 2rem; + width: 2rem; +} diff --git a/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.spec.ts b/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.spec.ts new file mode 100644 index 0000000..4292230 --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.spec.ts @@ -0,0 +1,22 @@ +import {ComponentFixture, TestBed} from '@angular/core/testing'; + +import {GanttScrollComponent} from './gantt-scroll.component'; + +describe('GanttScrollComponent', () => { + let component: GanttScrollComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [GanttScrollComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(GanttScrollComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.ts b/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.ts new file mode 100644 index 0000000..e6e7e6d --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/components/gantt-scroll/gantt-scroll.component.ts @@ -0,0 +1,28 @@ +import {Component, Inject} from '@angular/core'; +import {AnyObject} from '@project-lib/core/api'; +import {GANTT_SCALES} from '../../const'; +import {GanttService} from '../../services'; +import {GanttScaleService} from '../../types'; + +@Component({ + selector: 'arc-gantt-scroll', + templateUrl: './gantt-scroll.component.html', + styleUrls: ['./gantt-scroll.component.scss'], +}) +export class GanttScrollComponent { + constructor( + private ganttService: GanttService, + @Inject(GANTT_SCALES) + private readonly scales: GanttScaleService[], + ) {} + scrollBack() { + const selectedScale = this.ganttService.selectedScale; + const scale = this.scales.find(s => s.scale === selectedScale); + scale?.scroll(false, this.ganttService); + } + scrollForward() { + const selectedScale = this.ganttService.selectedScale; + const scale = this.scales.find(s => s.scale === selectedScale); + scale?.scroll(true, this.ganttService); + } +} diff --git a/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.html b/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.html new file mode 100644 index 0000000..9f73ce4 --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.html @@ -0,0 +1,11 @@ + + +
+ + + + + +
+
+
diff --git a/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.scss b/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.scss new file mode 100644 index 0000000..c4410ae --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.scss @@ -0,0 +1,8 @@ +.icon-wrapper { + display: flex; + gap: 16px; +} + +.icon { + cursor: pointer; +} diff --git a/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.spec.ts b/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.spec.ts new file mode 100644 index 0000000..84dcb3d --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.spec.ts @@ -0,0 +1,42 @@ +import {ComponentFixture, TestBed} from '@angular/core/testing'; + +import {GanttZoomBarComponent} from './gantt-zoombar.component'; +import {AnyObject} from '@project-lib/core/api'; +import {CoreModule} from '@project-lib/core/core.module'; +import {LocalizationModule} from '@project-lib/core/localization'; +import {IconPacksManagerService} from '@project-lib/theme/services'; +import {ThemeModule} from '@project-lib/theme/theme.module'; +import {GanttProviders, GANTT_SCALES} from '../../const'; + +describe('GanttZoomBarComponent', () => { + let component: GanttZoomBarComponent; + let fixture: ComponentFixture>; + let service: IconPacksManagerService; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [GanttZoomBarComponent], + providers: [ + GanttProviders, + { + provide: GANTT_SCALES, + useValue: [], + }, + ], + imports: [ThemeModule.forRoot('arc'), LocalizationModule, CoreModule], + }).compileComponents(); + service = TestBed.inject(IconPacksManagerService); + service.registerFontAwesome(); + service.registerSvgs(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(GanttZoomBarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.ts b/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.ts new file mode 100644 index 0000000..3b86896 --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/components/gantt-zoombar/gantt-zoombar.component.ts @@ -0,0 +1,34 @@ +import {Component} from '@angular/core'; +import {TranslateService} from '@ngx-translate/core'; +import {TranslationService} from '@project-lib/core/localization'; +import {GanttService} from '../../services'; +import {AnyObject} from '@project-lib/core/api'; +import {TimelineArray} from '../../types'; + +@Component({ + selector: 'arc-gantt-zoombar', + templateUrl: './gantt-zoombar.component.html', + styleUrls: ['./gantt-zoombar.component.scss'], +}) +export class GanttZoomBarComponent { + translate: TranslateService; + constructor( + private ganttService: GanttService, + private readonly translationService: TranslationService, + ) { + this.translate = this.translationService.translate; + console.log(TimelineArray); + } + + zoomIn() { + this.ganttService.zoomIn(); + } + + zoomOut() { + this.ganttService.zoomOut(); + } + + fitToScreen() { + this.ganttService.fitToScreen(); + } +} diff --git a/projects/arc-lib/src/lib/components/gantt/enum.ts b/projects/arc-lib/src/lib/components/gantt/enum.ts index 43c7383..a9285bf 100644 --- a/projects/arc-lib/src/lib/components/gantt/enum.ts +++ b/projects/arc-lib/src/lib/components/gantt/enum.ts @@ -1,11 +1,14 @@ -export enum GanttEventTypes { +export enum GanttEventValues { Kebab = 'kebab', Expand = 'expand', Name = 'name', Sort = 'sort', + SubAllocation = 'sub-allocation', Bar = 'bar', Tooltip = 'tooltip', Unknown = 'unknown', + OpenedTooltip = 'opened-tooltip', + ExpandBar = 'expand-bar', } export enum GanttScaleUnits { @@ -15,3 +18,8 @@ export enum GanttScaleUnits { Year = 'year', Quarter = 'quarter', } + +export enum GanttEventTypes { + Click = 'click', + Hover = 'hover', +} diff --git a/projects/arc-lib/src/lib/components/gantt/gantt.module.ts b/projects/arc-lib/src/lib/components/gantt/gantt.module.ts index c731dcb..1357dca 100644 --- a/projects/arc-lib/src/lib/components/gantt/gantt.module.ts +++ b/projects/arc-lib/src/lib/components/gantt/gantt.module.ts @@ -2,19 +2,13 @@ import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; import {ReactiveFormsModule} from '@angular/forms'; import {ThemeModule} from '@project-lib/theme/theme.module'; -import {GANTT, GANTT_SCALES} from './const'; +import {GANTT, GANTT_SCALES, GanttProviders} from './const'; import {MonthlyScaleService} from './services/timeline-scales/monthly-scale.service'; import {QuarterlyScaleService} from './services/timeline-scales/quarterly-scale.service'; import {WeeklyScaleService} from './services/timeline-scales/weekly-scale.service'; import {GanttRoutingModule} from './gantt-routing.module'; -import {GanttService} from './services'; import {gantt} from 'dhtmlx-gantt'; -import { - CustomGanttAdapter, - GanttAdapter, - GanttLib, - GanttScaleService, -} from './types'; +import {CustomGanttAdapter, GanttAdapter} from './types'; import { GanttBarsComponent, @@ -23,6 +17,9 @@ import { GanttTooltipComponent, } from './components'; import {NbInputModule} from '@nebular/theme/components/input/input.module'; +import {GanttZoomBarComponent} from './components/gantt-zoombar/gantt-zoombar.component'; +import {GanttScrollComponent} from './components/gantt-scroll/gantt-scroll.component'; +import {DateOperationService} from './services/date-operation.service'; @NgModule({ declarations: [ @@ -30,6 +27,8 @@ import {NbInputModule} from '@nebular/theme/components/input/input.module'; GanttColumnComponent, GanttHeaderComponent, GanttTooltipComponent, + GanttZoomBarComponent, + GanttScrollComponent, ], imports: [CommonModule, ReactiveFormsModule, ThemeModule, GanttRoutingModule], exports: [ @@ -37,9 +36,12 @@ import {NbInputModule} from '@nebular/theme/components/input/input.module'; GanttColumnComponent, GanttHeaderComponent, GanttTooltipComponent, + GanttZoomBarComponent, + GanttScrollComponent, ], providers: [ - GanttService, + GanttProviders, + DateOperationService, { provide: GANTT, useValue: gantt, diff --git a/projects/arc-lib/src/lib/components/gantt/services/date-operation.service.ts b/projects/arc-lib/src/lib/components/gantt/services/date-operation.service.ts new file mode 100644 index 0000000..3e99d73 --- /dev/null +++ b/projects/arc-lib/src/lib/components/gantt/services/date-operation.service.ts @@ -0,0 +1,45 @@ +import {Injectable} from '@angular/core'; +import * as moment from 'moment'; + +@Injectable() +export class DateOperationService { + convertToMoment(date: moment.MomentInput) { + return moment(date); + } + + getTotalMonths(startDate: moment.Moment, endDate: moment.Moment) { + let months = 0; + const date = startDate.clone().startOf('month'); + const end = endDate.clone().endOf('month'); + while (date < end) { + months++; + date.add(1, 'month'); + } + return months; + } + + calculateWeeksBetweenDates(startDate: Date | string, endDate: Date | string) { + const startMoment = moment(startDate); + const endMoment = moment(endDate); + const totalWeeks = endMoment.diff(startMoment, 'weeks') + 1; + return totalWeeks; + } + + getNumberOfDaysBetweenDates(date1: Date, date2: Date): number { + const momentDate1 = moment(date1); + const momentDate2 = moment(date2); + + const daysDifference = momentDate2.diff(momentDate1, 'days'); + + return daysDifference; + } + + getNumberOfMonthsBetweenDates(date1: Date, date2: Date): number { + const momentDate1 = moment(date1); + const momentDate2 = moment(date2); + + const monthsDifference = momentDate2.diff(momentDate1, 'months') + 1; + + return monthsDifference; + } +} diff --git a/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/monthly-scale.service.ts b/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/monthly-scale.service.ts index 2cd0d0e..cf4ff02 100644 --- a/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/monthly-scale.service.ts +++ b/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/monthly-scale.service.ts @@ -1,6 +1,9 @@ import {Injectable} from '@angular/core'; import {GanttScaleUnits} from '../../enum'; import {GanttScaleService, Timelines} from '../../types'; +import {AnyObject} from '@project-lib/core/api'; +import {DIGITS} from '@project-lib/core/constants'; +import {GanttService} from '../gantt.service'; @Injectable() export class MonthlyScaleService implements GanttScaleService { @@ -21,4 +24,29 @@ export class MonthlyScaleService implements GanttScaleService { }, ]; } + + scroll(forward: boolean, ganttService: GanttService): void { + const currentScrollState: number = ganttService.gantt.getScrollState().x; + const currentScrollDate: Date = + ganttService.gantt.dateFromPos(currentScrollState); + const newScrollDate: Date = ganttService.gantt.date.add( + currentScrollDate, + forward ? +DIGITS.ONE : -DIGITS.ONE, + 'month', + ); + const newScrollState: number = + ganttService.gantt.posFromDate(newScrollDate); + ganttService.gantt.scrollTo(newScrollState, null); + } + moveToToday(ganttService: GanttService): void { + const dateToday: Date = new Date(); + const newScrollDate: Date = ganttService.gantt.date.add( + dateToday, + -DIGITS.ONE, + 'month', + ); + const newScrollState: number = + ganttService.gantt.posFromDate(newScrollDate); + ganttService.gantt.scrollTo(newScrollState, null); + } } diff --git a/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/quarterly-scale.service.ts b/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/quarterly-scale.service.ts index c39eddb..fd9735c 100644 --- a/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/quarterly-scale.service.ts +++ b/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/quarterly-scale.service.ts @@ -2,6 +2,9 @@ import {Injectable} from '@angular/core'; import {MONTHS_IN_QUARTER} from '../../const'; import {GanttScaleUnits} from '../../enum'; import {GanttScaleService, Timelines} from '../../types'; +import {AnyObject} from '@project-lib/core/api'; +import {DIGITS} from '@project-lib/core/constants'; +import {GanttService} from '../gantt.service'; @Injectable() export class QuarterlyScaleService implements GanttScaleService { @@ -21,6 +24,30 @@ export class QuarterlyScaleService implements GanttScaleService { }, ]; } + scroll(forward: boolean, ganttService: GanttService): void { + const currentScrollState: number = ganttService.gantt.getScrollState().x; + const currentScrollDate: Date = + ganttService.gantt.dateFromPos(currentScrollState); + const newScrollDate: Date = ganttService.gantt.date.add( + currentScrollDate, + forward ? +DIGITS.FOUR : -DIGITS.FOUR, + 'month', + ); + const newScrollState: number = + ganttService.gantt.posFromDate(newScrollDate); + ganttService.gantt.scrollTo(newScrollState, null); + } + moveToToday(ganttService: GanttService): void { + const dateToday: Date = new Date(); + const newScrollDate: Date = ganttService.gantt.date.add( + dateToday, + -DIGITS.FOUR, + 'month', + ); + const newScrollState: number = + ganttService.gantt.posFromDate(newScrollDate); + ganttService.gantt.scrollTo(newScrollState, null); + } private _formatQuarterScale(date: Date) { const month = date.getMonth(); diff --git a/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/weekly-scale.service.ts b/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/weekly-scale.service.ts index efba020..747b8e3 100644 --- a/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/weekly-scale.service.ts +++ b/projects/arc-lib/src/lib/components/gantt/services/timeline-scales/weekly-scale.service.ts @@ -1,6 +1,9 @@ import {Injectable} from '@angular/core'; import {GanttScaleUnits} from '../../enum'; import {GanttScaleService, Timelines} from '../../types'; +import {AnyObject} from '@project-lib/core/api'; +import {DIGITS} from '@project-lib/core/constants'; +import {GanttService} from '../gantt.service'; @Injectable() export class WeeklyScaleService implements GanttScaleService { @@ -22,6 +25,30 @@ export class WeeklyScaleService implements GanttScaleService { ]; } + scroll(forward: boolean, ganttService: GanttService): void { + const currentScrollState: number = ganttService.gantt.getScrollState().x; + const currentScrollDate: Date = + ganttService.gantt.dateFromPos(currentScrollState); + const newScrollDate: Date = ganttService.gantt.date.add( + currentScrollDate, + forward ? +DIGITS.ONE : -DIGITS.ONE, + 'week', + ); + const newScrollState: number = + ganttService.gantt.posFromDate(newScrollDate); + ganttService.gantt.scrollTo(newScrollState, null); + } + moveToToday(ganttService: GanttService): void { + const dateToday: Date = new Date(); + const newScrollDate: Date = ganttService.gantt.date.add( + dateToday, + -DIGITS.ONE, + 'week', + ); + const newScrollState: number = + ganttService.gantt.posFromDate(newScrollDate); + ganttService.gantt.scrollTo(newScrollState, null); + } private _formatWeeklyScale(date: Date) { const noOfDigits = 2; return `${date.toLocaleString('default', {month: 'short'})} ${date