mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
[task overview, teams overview] nenaplanovany cas
This commit is contained in:
1 parent
8d49ad7122
commit
536fa40609
7 files changed
+283
-13944
No files matched your search
Generated
+189
-13925
File diff suppressed because it is too large.
Load diff
@@ -24,7 +24,7 @@
|
|||||||
"task_id": 2,
|
"task_id": 2,
|
||||||
"starts_at": "2023-01-11T08:30:00+00:00",
|
"starts_at": "2023-01-11T08:30:00+00:00",
|
||||||
"ends_at": "2023-01-11T09:00:00+00:00",
|
"ends_at": "2023-01-11T09:00:00+00:00",
|
||||||
"title": "Kratky 30min Lorem ipsum dolor sit amet, consectetur adipiscing e",
|
"title": "Kratky 30min",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#f27e57",
|
"master_task_color": "#f27e57",
|
||||||
"completed": false
|
"completed": false
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
"task_id": 2,
|
"task_id": 2,
|
||||||
"starts_at": "2023-01-11T08:30:00+00:00",
|
"starts_at": "2023-01-11T08:30:00+00:00",
|
||||||
"ends_at": "2023-01-11T09:00:00+00:00",
|
"ends_at": "2023-01-11T09:00:00+00:00",
|
||||||
"title": "Kratky 30min Lorem ipsum dolor sit amet, consectetur adipiscing e",
|
"title": "Kratky 30min",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#f27e57",
|
"master_task_color": "#f27e57",
|
||||||
"completed": false
|
"completed": false
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
"task_id": 2,
|
"task_id": 2,
|
||||||
"starts_at": "2023-01-11T08:30:00+00:00",
|
"starts_at": "2023-01-11T08:30:00+00:00",
|
||||||
"ends_at": "2023-01-11T09:00:00+00:00",
|
"ends_at": "2023-01-11T09:00:00+00:00",
|
||||||
"title": "Kratky 30min Lorem ipsum dolor sit amet, consectetur adipiscing e",
|
"title": "Kratky 30min",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#f27e57",
|
"master_task_color": "#f27e57",
|
||||||
"completed": false
|
"completed": false
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
"task_id": 2,
|
"task_id": 2,
|
||||||
"starts_at": "2023-01-11T08:30:00+00:00",
|
"starts_at": "2023-01-11T08:30:00+00:00",
|
||||||
"ends_at": "2023-01-11T09:00:00+00:00",
|
"ends_at": "2023-01-11T09:00:00+00:00",
|
||||||
"title": "Kratky 30min Lorem ipsum dolor sit amet, consectetur adipiscing e",
|
"title": "Kratky 30min",
|
||||||
"project_code": "CO-2201",
|
"project_code": "CO-2201",
|
||||||
"master_task_color": "#f27e57",
|
"master_task_color": "#f27e57",
|
||||||
"completed": false
|
"completed": false
|
||||||
|
|||||||
@@ -19,23 +19,31 @@
|
|||||||
<v-btn class="subheader-icon-button next" variant="outlined" @click="nextWeek()"><img :src="require('./_img/icon-next.svg')" alt=""></v-btn>
|
<v-btn class="subheader-icon-button next" variant="outlined" @click="nextWeek()"><img :src="require('./_img/icon-next.svg')" alt=""></v-btn>
|
||||||
</div>
|
</div>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
class="subheader-input"
|
class="subheader-input disabled"
|
||||||
label="Nenaplánované hodiny"
|
label="Nenaplánované hodiny"
|
||||||
v-model="plannedTime"
|
v-model="time"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
</v-row>
|
</v-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { startOfWeek, endOfWeek, addDays, subDays } from 'date-fns'
|
import { addDays, subDays } from 'date-fns'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
props: {
|
||||||
|
unscheduledTime: {
|
||||||
|
type: Number,
|
||||||
|
default() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
employees: ['Foo', 'Bar', 'Fizz', 'Buzz'],
|
employees: ['Foo', 'Bar', 'Fizz', 'Buzz'],
|
||||||
selectedDate: "13.11.2022 - 17.11.2022",
|
selectedDate: "13.11.2022 - 17.11.2022",
|
||||||
plannedTime: "35 h",
|
|
||||||
selectedEmployee: 'Bar',
|
selectedEmployee: 'Bar',
|
||||||
date: new Date()
|
date: new Date()
|
||||||
}
|
}
|
||||||
@@ -45,6 +53,12 @@ export default {
|
|||||||
this.getWeek()
|
this.getWeek()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
time() {
|
||||||
|
return this.unscheduledTime
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
getWeek() {
|
getWeek() {
|
||||||
this.firstDay = subDays(this.date, 1)
|
this.firstDay = subDays(this.date, 1)
|
||||||
|
|||||||
@@ -53,7 +53,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot:event="{ event }">
|
<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" @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="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 class="event-content">
|
<div class="event-content">
|
||||||
<small v-if="(event.project_code && !event.is_blocker)" class="project-code">{{ event.project_code }}</small>
|
<small v-if="(event.project_code && !event.is_blocker)" class="project-code">{{ event.project_code }}</small>
|
||||||
<h3>{{ event.title }}</h3>
|
<h3>{{ event.title }}</h3>
|
||||||
@@ -66,7 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="event-footer d-flex">
|
<div class="event-footer d-flex">
|
||||||
<v-btn rounded class="event-footer-button me-2" :class="{'completed': event.completed}" @click="this.showCompleteModal = {task: event}"><img :src="require('./_img/checkmark.svg')" alt=""></v-btn>
|
<v-btn rounded class="event-footer-button me-2" :class="{'completed': event.completed}" @click="clickCompleteTask(event)"><img :src="require('./_img/checkmark.svg')" alt=""></v-btn>
|
||||||
<v-btn rounded class="event-footer-button me-2" @click.stop="editTask(event.id, true)"><img :src="require('./_img/pencil.svg')" alt=""></v-btn>
|
<v-btn rounded class="event-footer-button me-2" @click.stop="editTask(event.id, true)"><img :src="require('./_img/pencil.svg')" alt=""></v-btn>
|
||||||
<v-btn rounded class="event-footer-button me-2" @click.stop="this.showDeleteModal = {task: event}"><img :src="require('./_img/bin.svg')" alt=""></v-btn>
|
<v-btn rounded class="event-footer-button me-2" @click.stop="this.showDeleteModal = {task: event}"><img :src="require('./_img/bin.svg')" alt=""></v-btn>
|
||||||
</div>
|
</div>
|
||||||
@@ -202,6 +203,11 @@ export default {
|
|||||||
// console.log(`Focused: ${event.task_id}`)
|
// console.log(`Focused: ${event.task_id}`)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clickCompleteTask(event) {
|
||||||
|
if (event.completed) this.$emit('reopenTask', event.id)
|
||||||
|
else this.showCompleteModal = {task: event}
|
||||||
|
},
|
||||||
|
|
||||||
completeTask(id) {
|
completeTask(id) {
|
||||||
this.$emit('completeTask', id)
|
this.$emit('completeTask', id)
|
||||||
},
|
},
|
||||||
@@ -342,8 +348,10 @@ export default {
|
|||||||
min-height: 40px
|
min-height: 40px
|
||||||
transition: min-height .4s, height .4s, box-shadow .4s, width .4s, left .4s
|
transition: min-height .4s, height .4s, box-shadow .4s, width .4s, left .4s
|
||||||
|
|
||||||
// &:has(.completed)
|
&:has(.completed)
|
||||||
// filter: grayscale(.9) !important
|
// filter: grayscale(.9) !important
|
||||||
|
// background: rgb(245, 245, 245) !important
|
||||||
|
// border: 1px solid rgb(224, 224, 224) !important
|
||||||
|
|
||||||
&:has(.non-working-event)
|
&:has(.non-working-event)
|
||||||
background: repeating-linear-gradient(135deg, rgba(215, 215, 215, 1), rgba(215, 215, 215, 1) 1px, rgba(224, 224, 224, 1) 1px, rgba(224, 224, 224, 1) 20px)
|
background: repeating-linear-gradient(135deg, rgba(215, 215, 215, 1), rgba(215, 215, 215, 1) 1px, rgba(224, 224, 224, 1) 1px, rgba(224, 224, 224, 1) 20px)
|
||||||
@@ -452,7 +460,7 @@ export default {
|
|||||||
width: fit-content
|
width: fit-content
|
||||||
|
|
||||||
&.completed
|
&.completed
|
||||||
background: #00B3A6
|
background: #06dece
|
||||||
|
|
||||||
img
|
img
|
||||||
width: 18px
|
width: 18px
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<A-task-filter @weekChange="getWeekData" />
|
<A-task-filter :unscheduledTime="unscheduledTime" @weekChange="getWeekData" />
|
||||||
|
|
||||||
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
|
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
|
||||||
<Z-timeline :calData="timelineData" :calConfig="config" :splits="splitDays" @eventMoved="onEventMoved" @completeTask="completeTask" @deleteTask="deleteTask" />
|
<Z-timeline :calData="timelineData" :calConfig="config" :splits="splitDays" @eventMoved="onEventMoved" @completeTask="completeTask" @reopenTask="reopenTask" @deleteTask="deleteTask" />
|
||||||
</W-loadable>
|
</W-loadable>
|
||||||
|
|
||||||
<v-snackbar
|
<v-snackbar
|
||||||
@@ -36,6 +36,7 @@ export default {
|
|||||||
errorToastMessage: "Nepodarilo sa nacitat data!",
|
errorToastMessage: "Nepodarilo sa nacitat data!",
|
||||||
dataLoaded: false,
|
dataLoaded: false,
|
||||||
splitDays: [],
|
splitDays: [],
|
||||||
|
unscheduledTime: 0,
|
||||||
config: {
|
config: {
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
scrollHour: 7,
|
scrollHour: 7,
|
||||||
@@ -87,11 +88,16 @@ export default {
|
|||||||
event.split = diffInDays * (-1) + 1
|
event.split = diffInDays * (-1) + 1
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.unscheduledTime = 0
|
||||||
|
|
||||||
this.timelineData.unscheduled_times.forEach(time => {
|
this.timelineData.unscheduled_times.forEach(time => {
|
||||||
time.name = this.timelineData.name
|
time.name = this.timelineData.name
|
||||||
time.surname = this.timelineData.surname
|
time.surname = this.timelineData.surname
|
||||||
|
this.unscheduledTime += time.time
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.unscheduledTime = Math.floor(this.unscheduledTime / 60) + "," + String(this.unscheduledTime % 60)[0] + " h"
|
||||||
|
|
||||||
this.config.scrollHour = Number(this.timelineData.work_hours_from.split(':')[0]) - 1
|
this.config.scrollHour = Number(this.timelineData.work_hours_from.split(':')[0]) - 1
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -154,6 +160,14 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
reopenTask(id) {
|
||||||
|
this.timelineData.tasks.filter(task => {
|
||||||
|
if (task.id == id) {
|
||||||
|
task.completed = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
deleteTask(id) {
|
deleteTask(id) {
|
||||||
this.timelineData.tasks.splice(this.timelineData.tasks.findIndex(item => item.id === id), 1)
|
this.timelineData.tasks.splice(this.timelineData.tasks.findIndex(item => item.id === id), 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,9 @@
|
|||||||
<v-btn class="subheader-icon-button next" variant="outlined" @click="nextDay()"><img :src="require('../../tasks/_components/_img/icon-next.svg')" alt=""></v-btn>
|
<v-btn class="subheader-icon-button next" variant="outlined" @click="nextDay()"><img :src="require('../../tasks/_components/_img/icon-next.svg')" alt=""></v-btn>
|
||||||
</div>
|
</div>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
class="subheader-input"
|
class="subheader-input disabled"
|
||||||
label="Nenaplánované hodiny"
|
label="Nenaplánované hodiny"
|
||||||
v-model="plannedTime"
|
v-model="time"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
</v-row>
|
</v-row>
|
||||||
@@ -31,12 +31,20 @@
|
|||||||
import { addDays, subDays } from 'date-fns'
|
import { addDays, subDays } from 'date-fns'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
props: {
|
||||||
|
unscheduledTime: {
|
||||||
|
type: Number,
|
||||||
|
default() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
employees: ['Foo', 'Bar', 'Fizz', 'Buzz'],
|
employees: ['Foo', 'Bar', 'Fizz', 'Buzz'],
|
||||||
selectedDate: new Date(),
|
selectedDate: new Date(),
|
||||||
day: new Date(),
|
day: new Date(),
|
||||||
plannedTime: "35 h",
|
|
||||||
selectedEmployee: 'Bar',
|
selectedEmployee: 'Bar',
|
||||||
date: new Date()
|
date: new Date()
|
||||||
}
|
}
|
||||||
@@ -46,6 +54,12 @@ export default {
|
|||||||
this.getDay()
|
this.getDay()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
time() {
|
||||||
|
return this.unscheduledTime
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
getDay() {
|
getDay() {
|
||||||
const today = new Date()
|
const today = new Date()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<A-team-filter @dayChanged="getDayData" />
|
<A-team-filter :unscheduledTime="unscheduledTime" @dayChanged="getDayData" />
|
||||||
|
|
||||||
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
|
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
|
||||||
<Z-timeline :calData="timelineData" :calConfig="config" :splits="splitDays" @eventMoved="onEventMoved" />
|
<Z-timeline :calData="timelineData" :calConfig="config" :splits="splitDays" @eventMoved="onEventMoved" @completeTask="completeTask" @reopenTask="reopenTask" @deleteTask="deleteTask" />
|
||||||
</W-loadable>
|
</W-loadable>
|
||||||
|
|
||||||
<v-snackbar
|
<v-snackbar
|
||||||
@@ -37,6 +37,7 @@ export default {
|
|||||||
errorToastMessage: "Nepodarilo sa nacitat data!",
|
errorToastMessage: "Nepodarilo sa nacitat data!",
|
||||||
dataLoaded: false,
|
dataLoaded: false,
|
||||||
splitDays: [],
|
splitDays: [],
|
||||||
|
unscheduledTime: 0,
|
||||||
config: {
|
config: {
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
scrollHour: 7,
|
scrollHour: 7,
|
||||||
@@ -75,6 +76,7 @@ export default {
|
|||||||
|
|
||||||
formatData() {
|
formatData() {
|
||||||
this.timelineData.tasks = []
|
this.timelineData.tasks = []
|
||||||
|
this.unscheduledTime = 0
|
||||||
|
|
||||||
// format events
|
// format events
|
||||||
this.timelineData.forEach(user => {
|
this.timelineData.forEach(user => {
|
||||||
@@ -87,7 +89,10 @@ export default {
|
|||||||
event.split = user.splitId
|
event.split = user.splitId
|
||||||
})
|
})
|
||||||
this.timelineData.tasks.push(...user.tasks)
|
this.timelineData.tasks.push(...user.tasks)
|
||||||
|
this.unscheduledTime += user.unscheduled_time
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.unscheduledTime = Math.floor(this.unscheduledTime / 60) + "," + String(this.unscheduledTime % 60)[0] + " h"
|
||||||
},
|
},
|
||||||
|
|
||||||
generateNonWorkingHours(date) {
|
generateNonWorkingHours(date) {
|
||||||
@@ -144,6 +149,26 @@ export default {
|
|||||||
// }
|
// }
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
},
|
||||||
|
|
||||||
|
completeTask(id) {
|
||||||
|
this.timelineData.tasks.filter(task => {
|
||||||
|
if (task.id == id) {
|
||||||
|
task.completed = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
reopenTask(id) {
|
||||||
|
this.timelineData.tasks.filter(task => {
|
||||||
|
if (task.id == id) {
|
||||||
|
task.completed = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteTask(id) {
|
||||||
|
this.timelineData.tasks.splice(this.timelineData.tasks.findIndex(item => item.id === id), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user