286 lines
9.1 KiB
TypeScript
286 lines
9.1 KiB
TypeScript
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<string, EventColor> = {
|
|
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<void> = new Subject<void>()
|
|
events: CalendarEvent[] = []
|
|
|
|
actions: CalendarEventAction[] = [
|
|
{
|
|
label: '<i class="fas fa-fw fa-pencil-alt"></i>',
|
|
a11yLabel: 'Edit',
|
|
onClick: ({ event }: { event: CalendarEvent }): void => {
|
|
this.eventClicked('Edit', event)
|
|
},
|
|
},
|
|
{
|
|
label: '<i class="fas fa-fw fa-trash-alt"></i>',
|
|
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);
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
}
|