import {Component, ViewChild} from '@angular/core'; import {NavigationLink, NavigationLinkListComponent} from "../../navigation-link-list/navigation-link-list.component"; import { AdvancedScheduleInfo, BasicScheduleInfo, ScheduleInfo, ScheduleService, TaskEntityInfo, TaskgroupEntityInfo, TaskOverviewInfo, TaskShortInfo } from "../../../api"; import {Subject} from "rxjs"; import {CalendarEvent, CalendarEventAction, CalendarEventTimesChangedEvent, CalendarView} from "angular-calendar"; import {TaskOverviewData} from "../../dashboard/taskgroup-overview/taskgroup-overview.component"; import {EventColor} from "calendar-utils"; import * as moment from "moment"; import {Router} from "@angular/router"; const colors: Record = { red: { primary: '#ad2121', secondary: '#FAE3E3', }, blue: { primary: '#1e90ff', secondary: '#D1E8FF', }, yellow: { primary: '#e3bc08', secondary: '#FDF1BA', }, }; @Component({ selector: 'app-draggable-scheduler', templateUrl: './draggable-scheduler.component.html', styleUrls: ['./draggable-scheduler.component.css'], styles: [ ` h3 { margin: 0 0 10px; } pre { background-color: #f5f5f5; padding: 15px; } `, ], }) export class DraggableSchedulerComponent { defaultNavigationLinkPath: NavigationLink[] = [ { linkText: "Dashboard", routerLink: ['/'] }, { linkText: "Taskgroups", routerLink: ["/taskgroups"] } ] taskgroups: TaskgroupEntityInfo[] = [] taskgroup: TaskgroupEntityInfo | undefined taskgroupPath: TaskgroupEntityInfo[] = [] taskgroupID: number = -1; scheduleID: number = -1; editedSchedule: ScheduleInfo | undefined @ViewChild('navLinkList') navLinkListComponent: NavigationLinkListComponent | undefined task: TaskEntityInfo | undefined scheduleStrategy: number = 1 /**************************************************/ //Calendar-Stuff /**************************************************/ view: CalendarView = CalendarView.Week; viewDate = new Date(); daysInWeek = 7; refresh: Subject = new Subject() events: CalendarEvent[] = [] actions: CalendarEventAction[] = [ { label: '', a11yLabel: 'Edit', onClick: ({ event }: { event: CalendarEvent }): void => { this.eventClicked('Edit', event) }, }, { label: '', a11yLabel: 'Delete', onClick: ({ event }: { event: CalendarEvent }): void => { this.eventClicked('Delete', event); }, }, ] tasks: CalendarEvent[] = [] selectedTaskgroupID: number | undefined constructor(private scheduleService: ScheduleService, private router: Router) { } ngOnInit() { this.scheduleService.schedulesGet().subscribe({ next: resp => { resp.forEach(schedule => { if(schedule.scheduleType == 'BASIC') { const basicSchedule = schedule as BasicScheduleInfo this.events.push({ title: this.computeTaskPath(schedule.taskgroupPath, schedule.task), color: colors['red'], start: new Date(basicSchedule.scheduleDate), actions: this.actions, allDay: true, draggable: true, resizable: { beforeStart: true, afterEnd: true }, meta: { taskID: schedule.task.taskID, scheduleID: schedule.scheduleID, taskgroupID: schedule.taskgroupPath[0].taskgroupID }, }) } else { const advancedSchedule = schedule as AdvancedScheduleInfo this.events.push({ title: this.computeTaskPath(schedule.taskgroupPath, schedule.task), color: colors['red'], cssClass: 'test', start: new Date(advancedSchedule.scheduleStartTime), end: new Date(advancedSchedule.scheduleStopTime), actions: this.actions, draggable: true, resizable: { beforeStart: true, afterEnd: true }, meta: { taskID: schedule.task.taskID, scheduleID: schedule.scheduleID, taskgroupID: schedule.taskgroupPath[0].taskgroupID }, }) } }); console.log(this.events) this.refresh.next(); } }) } onSelectTaskgroup(taskOverviewData: TaskOverviewData) { this.tasks = []; taskOverviewData.tasks.forEach(task => { this.tasks.push({ title: task.taskName, color: colors['yellow'], start: new Date(), draggable: true, cssClass: 'test', resizable: { beforeStart: true, afterEnd: true }, meta: { taskID: task.taskID, scheduleID: undefined, taskgroupID: taskOverviewData.taskgroupID }, actions: this.actions }) }) this.selectedTaskgroupID = taskOverviewData.taskgroupID; } externalDrop(event: CalendarEvent) { if (this.tasks.indexOf(event) === -1) { this.events = this.events.filter((iEvent) => iEvent !== event); this.tasks.push(event); } } eventDropped({ event, newStart, newEnd, allDay, }: CalendarEventTimesChangedEvent): void { const externalIndex = this.tasks.indexOf(event); if (typeof allDay !== 'undefined') { event.allDay = allDay; } if (externalIndex > -1) { this.tasks.splice(externalIndex, 1); this.events.push(event); } event.start = newStart; if (newEnd) { event.end = newEnd; } this.events = [...this.events]; if(externalIndex > -1) { //Create new schedule as a new event was dropped if(event.allDay) { this.scheduleService.schedulesTaskIDBasicPut(event.meta.taskID,{ scheduleDate: moment(event.start).format('YYYY-MM-DDTHH:mm:ss.SSSZ') }).subscribe({ next: resp => { event.meta.scheduleID = resp.scheduleID; event.color = colors['red']; event.title = this.computeTaskPath(resp.taskgroupPath, resp.task) } }) } else { console.log("Start: " + event.start); console.log("End: " + event.end); if(event.end == undefined) { event.end = moment(event.start).add(30, 'm').toDate() } this.scheduleService.schedulesTaskIDAdvancedPut(event.meta.taskID, { scheduleStartTime: moment(event.start).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), scheduleStopTime: moment(event.end).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), }).subscribe({ next: resp => { event.meta.scheduleID = resp.scheduleID; event.color = colors['red']; event.title = this.computeTaskPath(resp.taskgroupPath, resp.task) } }) } } else { if(event.allDay) { this.scheduleService.schedulesScheduleIDBasicPost(event.meta.scheduleID,{ scheduleDate: moment(event.start).format('YYYY-MM-DDTHH:mm:ss.SSSZ') }).subscribe({ next: resp => { console.log("Updated") } }) } else { this.scheduleService.schedulesScheduleIDAdvancedPost(event.meta.scheduleID, { scheduleStartTime: moment(event.start).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), scheduleStopTime: moment(event.end).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), }).subscribe({ next: resp => { console.log("Updated") } }) } } } computeTaskPath(taskgroupPath: TaskgroupEntityInfo[], task: TaskShortInfo | TaskEntityInfo) { let result = ""; taskgroupPath.forEach(taskgroupPathPart => { result += taskgroupPathPart.taskgroupName + "/" }); result += task!.taskName return result; } eventClicked(action: string, event: CalendarEvent): void { if(action == 'Click') { this.router.navigateByUrl("/taskgroups/" + event.meta.taskgroupID + "/tasks/" + event.meta.taskID); } else if(action == 'Edit') { this.router.navigateByUrl("/taskgroups/" + event.meta.taskgroupID + "/tasks/" + event.meta.taskID + "/schedule/" + event.meta.scheduleID); } else if(action == 'Delete') { this.scheduleService.schedulesScheduleIDDelete(event.meta.scheduleID).subscribe({ next: resp => { this.events = this.events.filter(calendarEvent => calendarEvent.meta.scheduleID !== event.meta.scheduleID); } }) } } }