[Blockers] Added blockers in tasks view

This commit is contained in:
Matej Glasnák committed 2023-03-21 20:41:10 +01:00
1 parent 04c42c2762
commit 6654c32da7
9 files changed
+260 -97

No files matched your search

@@ -57,30 +57,43 @@
</template>
<template v-slot:event="{ event }">
<!-- <div v-if="!event.nonWorking" @click.stop="editTask(event.id)" class="w-100 h-100 d-flex flex-column justify-space-between" :class="{'short-event' : getEventLenght(event) <= 9000000, 'mini-event' : getEventLenght(event) <= 5400000, 'micro-event' : getEventLenght(event) <= 3600000}"> -->
<div v-if="!event.nonWorking" class="custom-event-body w-100 h-100 d-flex flex-column justify-space-between" :class="{'short-event' : getEventLenght(event) <= 9000000, 'mini-event' : getEventLenght(event) <= 5400000, 'micro-event' : getEventLenght(event) <= 3600000}" :style="{backgroundColor: event.subtask.color}">
<div class="event-content">
<small v-if="(event.subtask.project_code && !event.is_blocker)" class="project-code">{{ event.subtask.project_code }}</small>
<h3>{{ event.subtask.master_task?.name || event.subtask.master_task }}</h3>
<div v-if="event.type == 'non-working-hours'" class="custom-event-body non-working-event w-100 h-100 d-flex flex-column justify-center">
<div class="d-flex justify-center align-center">
<v-icon icon="mdi-cancel" color="black"></v-icon>
<h3 class="mb-0 ms-2">{{ event.title }}</h3>
</div>
</div>
<div v-else class="custom-event-body w-100 h-100 d-flex flex-column justify-space-between" :class="{'short-event' : getEventLenght(event) <= 9000000, 'mini-event' : getEventLenght(event) <= 5400000, 'micro-event' : getEventLenght(event) <= 3600000}" :style="{backgroundColor: event.color || event.subtask.color}">
<div class="event-content" :class="event.type || 'subtask'">
<template v-if="event.type == 'blocker'">
<h3>{{ event.blocker.name }}</h3>
</template>
<template v-else>
<small v-if="event.subtask.project_code" class="project-code">{{ event.subtask.project_code }}</small>
<h3>{{ event.subtask.master_task?.name || event.subtask.master_task }}</h3>
</template>
<div class="d-flex align-center event-details event-initials-wrapper">
<div class="event-initials d-flex justify-center align-center">
<small>{{ event.initials }}</small>
</div>
<small class="event-initials-date">{{ event.start.toLocaleDateString('sk-SK') }}</small>
<small class="event-initials-date">{{ event.date.toLocaleDateString('sk-SK') }}</small>
</div>
</div>
<div class="event-footer d-flex">
<v-btn rounded class="event-footer-button me-2" :class="{'completed': event.subtask.is_finished}" @click.stop="completeTask(event)"><img :src="require('@/plugins/app/_img/icons/checkmark.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="editTask(event)"><img :src="require('@/plugins/app/_img/icons/eye.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="deleteTask(event)"><img :src="require('@/plugins/app/_img/icons/bin.svg')" alt=""></v-btn>
</div>
</div>
<template v-if="event.type == 'blocker'">
<v-btn rounded class="event-footer-button me-2" @click.stop="editBlocker(event)"><img :src="require('@/plugins/app/_img/icons/pencil.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="deleteBlocker(event)"><img :src="require('@/plugins/app/_img/icons/bin.svg')" alt=""></v-btn>
</template>
<div v-else class="custom-event-body non-working-event w-100 h-100 d-flex flex-column justify-center">
<div class="d-flex justify-center align-center">
<v-icon icon="mdi-cancel" color="black"></v-icon>
<h3 class="mb-0 ms-2">{{ event.title }}</h3>
<template v-else>
<v-btn rounded class="event-footer-button me-2" :class="{'completed': event.subtask?.is_finished}" @click.stop="completeTask(event)"><img :src="require('@/plugins/app/_img/icons/checkmark.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="editTask(event)"><img :src="require('@/plugins/app/_img/icons/eye.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="deleteTask(event)"><img :src="require('@/plugins/app/_img/icons/bin.svg')" alt=""></v-btn>
</template>
</div>
</div>
</template>
@@ -196,7 +209,7 @@ export default {
},
taskClicked(subtask) {
if (subtask.nonWorking) return
if (subtask.type == 'non-working-hours') return
// console.log("task", task)
if (subtask.end.getTime() - subtask.start.getTime() <= 3600000) {
// console.log("ShortTask")
@@ -212,13 +225,21 @@ export default {
this.$events.emit('show-complete-task-modal', { subtask })
},
editTask(subtask, editMode) {
this.$events.emit('show-subtask-modal', {subtask, editMode})
editTask({subtask}) {
this.$events.emit('show-subtask-modal', {subtask})
},
deleteTask(subtask) {
deleteTask({ subtask }) {
this.$events.emit('show-delete-task-modal', {subtask})
}
},
editBlocker({ blocker }) {
this.$events.emit('show-blocker-modal', {blocker})
},
deleteBlocker({ blocker }) {
this.$events.emit('show-delete-blocker-modal', {blocker})
},
}
}
</script>
@@ -363,6 +384,17 @@ export default {
.custom-event-body
padding: 20px 10px
.event-content
&.blocker
*
color: #ffffff !important
.event-details .event-initials
border: 1px solid white
.event-footer
border-top: 1px solid rgba(255, 255, 255, 0.19)
&:has(.completed)
background: rgb(251, 251, 251) !important
border: 1px solid #cccccc !important
@@ -378,12 +410,11 @@ export default {
left: 0 !important
&:not(.vuecal__event--focus)
&:has(.short-event)
padding: 10px !important
&:has(.micro-event)
padding: 5px 10px !important
&:has(.micro-event) .custom-event-body
padding: 5px !important
&:has(.short-event) .custom-event-body:not(.micro-event)
padding: 10px 5px !important
.short-event
.project-code
display: none !important
@@ -420,19 +451,6 @@ export default {
.event-footer
display: none !important
&.event-blocker
background: #B00020 !important
h3,
.event-details *
color: white !important
.event-details .event-initials
border: 1px solid white
.event-footer
border-top: 1px solid rgba(255, 255, 255, 0.19)
.project-code
margin: 0 0 20px
display: block
@@ -21,13 +21,17 @@ export default {
},
generateTimelineEvents(subtasks, employee, date) {
const events = []
let events = []
subtasks.forEach(subtask => {
subtask.timeblocks?.forEach((timeblock) => {
events.push(this._composeTimelineEvent(subtask, employee, date, timeblock))
})
})
if (subtask.type == 'blocker') {
events = [...events, ...this._generateEventsFromBlocker(subtask, date)]
} else {
subtask.timeblocks?.forEach((timeblock) => {
events.push(this._composeTimelineEvent(subtask, employee, date, timeblock))
})
}
})
return events
},
@@ -50,30 +54,72 @@ export default {
}
},
_generateEventsFromBlocker(blocker, date) {
const start = moment(blocker.start)
const end = moment(blocker.end)
const dates = start == end ? [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',
initials: `${blocker.employee?.name[0]}${blocker.employee?.surname[0]}`,
color: '#B00020',
draggable: false
}
})
console.log(blockers)
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 nonWorkingHours = []
const events = []
for (let i = 0; i < 7; i++) {
nonWorkingHours.push({
events.push({
title: "Non working hours",
start: setMinutes(setHours(date, 0), 0),
end: setMinutes(setHours(date, employee.work_start), 0),
nonWorking: true,
type: 'non-working-hours',
split: i + 1,
draggable: false
})
nonWorkingHours.push({
events.push({
title: "Non working hours",
start: setMinutes(setHours(date, employee.work_end), 0),
end: setMinutes(setHours(date, 23), 59),
nonWorking: true,
type: 'non-working-hours',
split: i + 1,
draggable: false
})
}
return nonWorkingHours
return events
},
_getSplitFromDate(date, start) {
+13 -5
View File
@@ -43,7 +43,7 @@ export default {
if (!workingHours[task.split])
workingHours[task.split] = 0
if (task.nonWorking || task.subtask.is_finished)
if (task.type == 'non-working-hours' || task.subtask?.is_finished || task.blocker?.is_finished)
return
workingHours[task.split] += timelineUtils._getDifferenceInHours(task.end, task.start)
@@ -88,9 +88,17 @@ export default {
this.onFilterChanged(this.filter)
})
this.$events.on('on-blocker-edited', () => {
this.onFilterChanged(this.filter)
})
this.$events.on('on-subtask-deleted', () => {
this.onFilterChanged(this.filter)
})
this.$events.on('on-blocker-deleted', () => {
this.onFilterChanged(this.filter)
})
},
unmounted() {
@@ -110,10 +118,10 @@ export default {
const queryParameters = new URLSearchParams(urlQueryObject).toString()
try {
const { subtasks } = await this.$axios.get_auth(`v1/subtasks?${queryParameters}`)
this.config.scrollHour = this.filter?.employee.work_start - 1
this.config.date = this.filter.start
this.subtasks = subtasks
const { subtasks, blockers } = await this.$axios.get_auth(`v1/subtasks?${queryParameters}`)
this.config.scrollHour = this.filter?.employee.work_start - 1
this.config.date = this.filter.start
this.subtasks = [...subtasks, ...blockers.map(blocker => ({...blocker, type: 'blocker'}))]
} catch (error) {
console.log(error)
this.$toast.error('Nepodarilo sa nacitat data!')
+3 -11
View File
@@ -57,15 +57,7 @@ export default {
timelineData() {
if (!this.subtasks)
return
// let unscheduledTime = 0
// const tasks = [...this._generateNonWorking(), ...this._generateTasks()]
// tasks.forEach(task => {
// if (!task.nonWorking)
// workingHours += timelineUtils._getDifferenceInHours(task.end, task.start)
// })
return
return {
unscheduledTime: 333,
@@ -147,7 +139,7 @@ export default {
start: setMinutes(setHours(date, 0), 0),
end: setMinutes(setHours(date, employee.work_start), 0),
split: index + 1,
nonWorking: true,
type: 'non-working-hours',
draggable: false
})
@@ -156,7 +148,7 @@ export default {
start: setMinutes(setHours(date, employee.work_end), 0),
end: setMinutes(setHours(date, 23), 59),
split: index + 1,
nonWorking: true,
type: 'non-working-hours',
draggable: false
})
})