mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
164 lines
4.4 KiB
TypeScript
164 lines
4.4 KiB
TypeScript
import { setHours, setMinutes, addDays, differenceInCalendarDays } from 'date-fns'
|
|
import moment from 'moment'
|
|
|
|
export default {
|
|
generateTimelineTasks(subtasks, date, employee) {
|
|
const { tasks, blockers, homeoffices } = this.generateTimelineEvents(subtasks, employee, date)
|
|
const { nonWorkingHours } = this.generateTimelineNonWorkingHours(date, employee)
|
|
|
|
return {
|
|
tasks,
|
|
blockers,
|
|
nonWorkingHours,
|
|
homeoffices
|
|
}
|
|
},
|
|
|
|
getUnscheduledTime(subtasks) {
|
|
let unscheduledTime = 0
|
|
subtasks.forEach(subtask => unscheduledTime += (subtask.duration - subtask.spent_time))
|
|
|
|
return unscheduledTime
|
|
},
|
|
|
|
isWeekend(date) {
|
|
return moment(date).day() % 6 == 0
|
|
},
|
|
|
|
generateTimelineEvents(subtasks, employee, date) {
|
|
let blockers = []
|
|
const tasks = []
|
|
|
|
subtasks.forEach(subtask => {
|
|
if (['blocker', 'adhoc', 'home_office', 'vacation', 'free_day'].includes(subtask.type)) {
|
|
blockers = [...blockers, ...this._generateEventsFromBlocker(subtask, date)]
|
|
} else {
|
|
subtask.timeblocks?.forEach((timeblock) => {
|
|
tasks.push(this._composeTimelineEvent(subtask, employee, date, timeblock))
|
|
})
|
|
}
|
|
})
|
|
|
|
return {
|
|
tasks,
|
|
blockers: blockers.filter(blocker => blocker.type != 'home_office'),
|
|
homeoffices: blockers.filter(blocker => blocker.type == 'home_office')
|
|
}
|
|
},
|
|
|
|
_composeTimelineEvent(subtask, employee, date, timeblock) {
|
|
const diffInDays = differenceInCalendarDays(date, new Date(timeblock.start))
|
|
|
|
return {
|
|
id: subtask.id,
|
|
start: addDays(new Date(timeblock.start), diffInDays),
|
|
end: addDays(new Date(timeblock.end), diffInDays),
|
|
master_task: subtask.master_task,
|
|
date: new Date(timeblock.start),
|
|
isWeekend: this.isWeekend(timeblock.start),
|
|
initials: employee.name.charAt(0).toUpperCase() + employee.surname.charAt(0).toUpperCase(),
|
|
split: this._getSplitFromDate(date, timeblock.start),
|
|
project_code: subtask.project_code,
|
|
subtask: subtask,
|
|
type: 'subtask',
|
|
_timeblock_id: timeblock.id,
|
|
_real_start: new Date(timeblock.start),
|
|
_real_end: new Date(timeblock.end)
|
|
}
|
|
},
|
|
|
|
_generateEventsFromBlocker(blocker, date) {
|
|
const start = moment(blocker.start)
|
|
const end = moment(blocker.end)
|
|
|
|
const dates = start.isSame(end, 'date') ? [moment(start).format('YYYY-MM-DD')] : this._getDatesInRange(start, end)
|
|
const blockers = dates.map(d => {
|
|
const diffInDays = differenceInCalendarDays(date, new Date(d))
|
|
const dStart = new Date(moment(d).set({hours: start.hours(), minutes: start.minutes()}).format('YYYY-MM-DD HH:mm'))
|
|
const dEnd = new Date(moment(d).set({hours: end.hours(), minutes: end.minutes()}).format('YYYY-MM-DD HH:mm'))
|
|
|
|
return {
|
|
blocker,
|
|
split: this._getSplitFromDate(date, d),
|
|
start: addDays(dStart, diffInDays),
|
|
end: addDays(dEnd, diffInDays),
|
|
date: new Date(d),
|
|
type: blocker.type,
|
|
isBlocker: true,
|
|
initials: `${blocker.employee?.name[0]}${blocker.employee?.surname[0]}`,
|
|
color: '#B00020',
|
|
draggable: false,
|
|
_real_start: dStart,
|
|
_real_end: dEnd
|
|
}
|
|
})
|
|
|
|
return blockers
|
|
},
|
|
|
|
_getDatesInRange(start, end) {
|
|
const dates = []
|
|
|
|
while (start <= end) {
|
|
dates.push(moment(start).format('YYYY-MM-DD'))
|
|
start.add(1, 'day')
|
|
}
|
|
|
|
return dates
|
|
},
|
|
|
|
generateTimelineNonWorkingHours(date, employee) {
|
|
const events = []
|
|
|
|
const { start: dayStart, end: dayEnd } = this._getDayStartEnd(date)
|
|
|
|
for (let i = 0; i < 7; i++) {
|
|
events.push({
|
|
title: "Non working hours",
|
|
start: dayStart,
|
|
end: this._setMinutesToDate(employee.work_start, date),
|
|
type: 'non-working-hours',
|
|
split: i + 1,
|
|
draggable: false
|
|
})
|
|
|
|
events.push({
|
|
title: "Non working hours",
|
|
start: this._setMinutesToDate(employee.work_end, date),
|
|
end: dayEnd,
|
|
type: 'non-working-hours',
|
|
split: i + 1,
|
|
draggable: false
|
|
})
|
|
}
|
|
|
|
return {nonWorkingHours: events}
|
|
},
|
|
|
|
_getSplitFromDate(date, start) {
|
|
return differenceInCalendarDays(new Date(date), new Date(start)) * (-1) + 1
|
|
},
|
|
|
|
_getDifferenceInHours(date1, date2) {
|
|
return this._getDifferenceInMinutes(date1, date2) / 60
|
|
},
|
|
|
|
_getDifferenceInMinutes(date1, date2) {
|
|
let diff = (date1.getTime() - date2.getTime()) / 1000
|
|
diff /= 60
|
|
return Math.abs(Math.round(diff))
|
|
},
|
|
|
|
_getDayStartEnd(date) {
|
|
return {
|
|
start: this._setMinutesToDate(0, date),
|
|
end: this._setMinutesToDate(1439, date)
|
|
}
|
|
},
|
|
|
|
_setMinutesToDate(minutes, date) {
|
|
const newDate = new Date(date)
|
|
newDate.setHours(Math.floor(minutes / 60), minutes % 60, 0, 0)
|
|
return newDate
|
|
}
|
|
} |